[libc++] Refactor __libcpp_is_trivially_equality_comparable to be a variable template (#173151)
This commit is contained in:
parent
24cd0746e8
commit
663f9d189a
@ -184,7 +184,7 @@ template <class _Tp,
|
||||
class _Up,
|
||||
class _BinaryPredicate,
|
||||
__enable_if_t<__desugars_to_v<__equal_tag, _BinaryPredicate, _Tp, _Up> && !is_volatile<_Tp>::value &&
|
||||
!is_volatile<_Up>::value && __libcpp_is_trivially_equality_comparable<_Tp, _Up>::value,
|
||||
!is_volatile<_Up>::value && __is_trivially_equality_comparable_v<_Tp, _Up>,
|
||||
int> = 0>
|
||||
[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
|
||||
__equal_iter_impl(_Tp* __first1, _Tp* __last1, _Up* __first2, _BinaryPredicate&) {
|
||||
@ -225,7 +225,7 @@ template <class _Tp,
|
||||
class _Proj2,
|
||||
__enable_if_t<__desugars_to_v<__equal_tag, _Pred, _Tp, _Up> && __is_identity<_Proj1>::value &&
|
||||
__is_identity<_Proj2>::value && !is_volatile<_Tp>::value && !is_volatile<_Up>::value &&
|
||||
__libcpp_is_trivially_equality_comparable<_Tp, _Up>::value,
|
||||
__is_trivially_equality_comparable_v<_Tp, _Up>,
|
||||
int> = 0>
|
||||
[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
|
||||
__equal_impl(_Tp* __first1, _Tp* __last1, _Up* __first2, _Up*, _Pred&, _Proj1&, _Proj2&) {
|
||||
|
||||
@ -114,11 +114,10 @@ _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp* __find_vectorized(_Tp* __first, _Tp* __last,
|
||||
|
||||
#ifndef _LIBCPP_CXX03_LANG
|
||||
// trivially equality comparable implementations
|
||||
template <
|
||||
class _Tp,
|
||||
class _Up,
|
||||
class _Proj,
|
||||
__enable_if_t<__is_identity<_Proj>::value && __libcpp_is_trivially_equality_comparable<_Tp, _Up>::value, int> = 0>
|
||||
template <class _Tp,
|
||||
class _Up,
|
||||
class _Proj,
|
||||
__enable_if_t<__is_identity<_Proj>::value && __is_trivially_equality_comparable_v<_Tp, _Up>, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp* __find(_Tp* __first, _Tp* __last, const _Up& __value, _Proj&) {
|
||||
if constexpr (sizeof(_Tp) == 1) {
|
||||
if (auto __ret = std::__constexpr_memchr(__first, __value, __last - __first))
|
||||
@ -149,7 +148,7 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp* __find(_Tp* __first, _T
|
||||
template <class _Tp,
|
||||
class _Up,
|
||||
class _Proj,
|
||||
__enable_if_t<__is_identity<_Proj>::value && !__libcpp_is_trivially_equality_comparable<_Tp, _Up>::value &&
|
||||
__enable_if_t<__is_identity<_Proj>::value && !__is_trivially_equality_comparable_v<_Tp, _Up> &&
|
||||
is_integral<_Tp>::value && is_integral<_Up>::value &&
|
||||
is_signed<_Tp>::value == is_signed<_Up>::value,
|
||||
int> = 0>
|
||||
|
||||
@ -66,8 +66,8 @@ template <class _Tp,
|
||||
class _Proj2,
|
||||
class _Comp,
|
||||
__enable_if_t<__desugars_to_v<__totally_ordered_less_tag, _Comp, _Tp, _Tp> && !is_volatile<_Tp>::value &&
|
||||
__libcpp_is_trivially_equality_comparable<_Tp, _Tp>::value &&
|
||||
__is_identity<_Proj1>::value && __is_identity<_Proj2>::value,
|
||||
__is_trivially_equality_comparable_v<_Tp, _Tp> && __is_identity<_Proj1>::value &&
|
||||
__is_identity<_Proj2>::value,
|
||||
int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
|
||||
__lexicographical_compare(_Tp* __first1, _Tp* __last1, _Tp* __first2, _Tp* __last2, _Comp&, _Proj1&, _Proj2&) {
|
||||
|
||||
@ -136,7 +136,7 @@ template <class _Tp,
|
||||
class _Proj2,
|
||||
__enable_if_t<!is_integral<_Tp>::value && __desugars_to_v<__equal_tag, _Pred, _Tp, _Tp> &&
|
||||
__is_identity<_Proj1>::value && __is_identity<_Proj2>::value &&
|
||||
__can_map_to_integer_v<_Tp> && __libcpp_is_trivially_equality_comparable<_Tp, _Tp>::value,
|
||||
__can_map_to_integer_v<_Tp> && __is_trivially_equality_comparable_v<_Tp, _Tp>,
|
||||
int> = 0>
|
||||
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_Tp*, _Tp*>
|
||||
__mismatch(_Tp* __first1, _Tp* __last1, _Tp* __first2, _Pred& __pred, _Proj1& __proj1, _Proj2& __proj2) {
|
||||
|
||||
@ -95,14 +95,13 @@ __constexpr_memcmp(const _Tp* __lhs, const _Up* __rhs, __element_count __n) {
|
||||
}
|
||||
}
|
||||
|
||||
// Because of __libcpp_is_trivially_equality_comparable we know that comparing the object representations is equivalent
|
||||
// Because of __is_trivially_equality_comparable_v we know that comparing the object representations is equivalent
|
||||
// to a std::memcmp(...) == 0. Since we have multiple objects contiguously in memory, we can call memcmp once instead
|
||||
// of invoking it on every object individually.
|
||||
template <class _Tp, class _Up>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool
|
||||
__constexpr_memcmp_equal(const _Tp* __lhs, const _Up* __rhs, __element_count __n) {
|
||||
static_assert(__libcpp_is_trivially_equality_comparable<_Tp, _Up>::value,
|
||||
"_Tp and _Up have to be trivially equality comparable");
|
||||
static_assert(__is_trivially_equality_comparable_v<_Tp, _Up>, "_Tp and _Up have to be trivially equality comparable");
|
||||
|
||||
auto __count = static_cast<size_t>(__n);
|
||||
|
||||
@ -127,7 +126,7 @@ __constexpr_memcmp_equal(const _Tp* __lhs, const _Up* __rhs, __element_count __n
|
||||
|
||||
template <class _Tp, class _Up>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp* __constexpr_memchr(_Tp* __str, _Up __value, size_t __count) {
|
||||
static_assert(sizeof(_Tp) == 1 && __libcpp_is_trivially_equality_comparable<_Tp, _Up>::value,
|
||||
static_assert(sizeof(_Tp) == 1 && __is_trivially_equality_comparable_v<_Tp, _Up>,
|
||||
"Calling memchr on non-trivially equality comparable types is unsafe.");
|
||||
|
||||
if (__libcpp_is_constant_evaluated()) {
|
||||
|
||||
@ -27,11 +27,11 @@
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _Tp, class _Up, class = void>
|
||||
struct __is_equality_comparable : false_type {};
|
||||
inline const bool __is_equality_comparable_v = false;
|
||||
|
||||
template <class _Tp, class _Up>
|
||||
struct __is_equality_comparable<_Tp, _Up, __void_t<decltype(std::declval<_Tp>() == std::declval<_Up>())> > : true_type {
|
||||
};
|
||||
inline const bool
|
||||
__is_equality_comparable_v<_Tp, _Up, __void_t<decltype(std::declval<_Tp>() == std::declval<_Up>())> > = true;
|
||||
|
||||
// A type is_trivially_equality_comparable if the expression `a == b` is equivalent to `std::memcmp(&a, &b, sizeof(T))`
|
||||
// (with `a` and `b` being of type `T`). For the case where we compare two object of the same type, we can use
|
||||
@ -48,40 +48,35 @@ struct __is_equality_comparable<_Tp, _Up, __void_t<decltype(std::declval<_Tp>()
|
||||
// representation may not be equivalent.
|
||||
|
||||
template <class _Tp, class _Up, class = void>
|
||||
struct __libcpp_is_trivially_equality_comparable_impl : false_type {};
|
||||
inline const bool __is_trivially_equality_comparable_impl = false;
|
||||
|
||||
template <class _Tp>
|
||||
struct __libcpp_is_trivially_equality_comparable_impl<_Tp, _Tp>
|
||||
inline const bool __is_trivially_equality_comparable_impl<_Tp, _Tp>
|
||||
#if __has_builtin(__is_trivially_equality_comparable)
|
||||
: integral_constant<bool, __is_trivially_equality_comparable(_Tp) && __is_equality_comparable<_Tp, _Tp>::value> {
|
||||
};
|
||||
= __is_trivially_equality_comparable(_Tp) && __is_equality_comparable_v<_Tp, _Tp>;
|
||||
#else
|
||||
: is_integral<_Tp> {
|
||||
};
|
||||
= is_integral<_Tp>::value;
|
||||
#endif // __has_builtin(__is_trivially_equality_comparable)
|
||||
|
||||
template <class _Tp, class _Up>
|
||||
struct __libcpp_is_trivially_equality_comparable_impl<
|
||||
inline const bool __is_trivially_equality_comparable_impl<
|
||||
_Tp,
|
||||
_Up,
|
||||
__enable_if_t<is_integral<_Tp>::value && is_integral<_Up>::value && !is_same<_Tp, _Up>::value &&
|
||||
is_signed<_Tp>::value == is_signed<_Up>::value && sizeof(_Tp) == sizeof(_Up)> > : true_type {};
|
||||
__enable_if_t<is_integral<_Tp>::value && is_integral<_Up>::value && !is_same<_Tp, _Up>::value> > =
|
||||
is_signed<_Tp>::value == is_signed<_Up>::value && sizeof(_Tp) == sizeof(_Up);
|
||||
|
||||
template <class _Tp>
|
||||
struct __libcpp_is_trivially_equality_comparable_impl<_Tp*, _Tp*> : true_type {};
|
||||
inline const bool __is_trivially_equality_comparable_impl<_Tp*, _Tp*> = true;
|
||||
|
||||
// TODO: Use is_pointer_inverconvertible_base_of
|
||||
template <class _Tp, class _Up>
|
||||
struct __libcpp_is_trivially_equality_comparable_impl<_Tp*, _Up*>
|
||||
: integral_constant<
|
||||
bool,
|
||||
__is_equality_comparable<_Tp*, _Up*>::value &&
|
||||
(is_same<__remove_cv_t<_Tp>, __remove_cv_t<_Up> >::value || is_void<_Tp>::value || is_void<_Up>::value)> {
|
||||
};
|
||||
inline const bool __is_trivially_equality_comparable_impl<_Tp*, _Up*> =
|
||||
__is_equality_comparable_v<_Tp*, _Up*> &&
|
||||
(is_same<__remove_cv_t<_Tp>, __remove_cv_t<_Up> >::value || is_void<_Tp>::value || is_void<_Up>::value);
|
||||
|
||||
template <class _Tp, class _Up>
|
||||
using __libcpp_is_trivially_equality_comparable _LIBCPP_NODEBUG =
|
||||
__libcpp_is_trivially_equality_comparable_impl<__remove_cv_t<_Tp>, __remove_cv_t<_Up> >;
|
||||
inline const bool __is_trivially_equality_comparable_v =
|
||||
__is_trivially_equality_comparable_impl<__remove_cv_t<_Tp>, __remove_cv_t<_Up> >;
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
|
||||
@ -231,8 +231,8 @@ __constexpr_wmemcmp(const wchar_t* __lhs, const wchar_t* __rhs, size_t __count)
|
||||
|
||||
template <class _Tp, class _Up>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp* __constexpr_wmemchr(_Tp* __str, _Up __value, size_t __count) {
|
||||
static_assert(sizeof(_Tp) == sizeof(wchar_t)&& _LIBCPP_ALIGNOF(_Tp) >= _LIBCPP_ALIGNOF(wchar_t) &&
|
||||
__libcpp_is_trivially_equality_comparable<_Tp, _Tp>::value,
|
||||
static_assert(sizeof(_Tp) == sizeof(wchar_t) && _LIBCPP_ALIGNOF(_Tp) >= _LIBCPP_ALIGNOF(wchar_t) &&
|
||||
__is_trivially_equality_comparable_v<_Tp, _Tp>,
|
||||
"Calling wmemchr on non-trivially equality comparable types is unsafe.");
|
||||
|
||||
# if __has_builtin(__builtin_wmemchr)
|
||||
|
||||
@ -14,38 +14,38 @@
|
||||
enum Enum : int {};
|
||||
enum class EnumClass : int {};
|
||||
|
||||
static_assert(std::__libcpp_is_trivially_equality_comparable<int, int>::value, "");
|
||||
static_assert(std::__libcpp_is_trivially_equality_comparable<const int, int>::value, "");
|
||||
static_assert(std::__libcpp_is_trivially_equality_comparable<int, const int>::value, "");
|
||||
static_assert(std::__is_trivially_equality_comparable_v<int, int>, "");
|
||||
static_assert(std::__is_trivially_equality_comparable_v<const int, int>, "");
|
||||
static_assert(std::__is_trivially_equality_comparable_v<int, const int>, "");
|
||||
|
||||
static_assert(std::__libcpp_is_trivially_equality_comparable<unsigned int, unsigned int>::value, "");
|
||||
static_assert(std::__libcpp_is_trivially_equality_comparable<const unsigned int, unsigned int>::value, "");
|
||||
static_assert(!std::__libcpp_is_trivially_equality_comparable<unsigned int, int>::value, "");
|
||||
static_assert(std::__is_trivially_equality_comparable_v<unsigned int, unsigned int>, "");
|
||||
static_assert(std::__is_trivially_equality_comparable_v<const unsigned int, unsigned int>, "");
|
||||
static_assert(!std::__is_trivially_equality_comparable_v<unsigned int, int>, "");
|
||||
|
||||
static_assert(!std::__libcpp_is_trivially_equality_comparable<std::int32_t, std::int64_t>::value, "");
|
||||
static_assert(!std::__libcpp_is_trivially_equality_comparable<std::int64_t, std::int32_t>::value, "");
|
||||
static_assert(!std::__is_trivially_equality_comparable_v<std::int32_t, std::int64_t>, "");
|
||||
static_assert(!std::__is_trivially_equality_comparable_v<std::int64_t, std::int32_t>, "");
|
||||
|
||||
static_assert(std::__libcpp_is_trivially_equality_comparable<int*, int*>::value, "");
|
||||
static_assert(std::__libcpp_is_trivially_equality_comparable<int*, void*>::value, "");
|
||||
static_assert(!std::__libcpp_is_trivially_equality_comparable<int*, long*>::value, "");
|
||||
static_assert(std::__is_trivially_equality_comparable_v<int*, int*>, "");
|
||||
static_assert(std::__is_trivially_equality_comparable_v<int*, void*>, "");
|
||||
static_assert(!std::__is_trivially_equality_comparable_v<int*, long*>, "");
|
||||
|
||||
static_assert(!std::__libcpp_is_trivially_equality_comparable<Enum, int>::value, "");
|
||||
static_assert(!std::__libcpp_is_trivially_equality_comparable<EnumClass, int>::value, "");
|
||||
static_assert(!std::__is_trivially_equality_comparable_v<Enum, int>, "");
|
||||
static_assert(!std::__is_trivially_equality_comparable_v<EnumClass, int>, "");
|
||||
|
||||
static_assert(!std::__libcpp_is_trivially_equality_comparable<float, int>::value, "");
|
||||
static_assert(!std::__libcpp_is_trivially_equality_comparable<double, long long>::value, "");
|
||||
static_assert(!std::__is_trivially_equality_comparable_v<float, int>, "");
|
||||
static_assert(!std::__is_trivially_equality_comparable_v<double, long long>, "");
|
||||
|
||||
static_assert(!std::__libcpp_is_trivially_equality_comparable<float, int>::value, "");
|
||||
static_assert(!std::__is_trivially_equality_comparable_v<float, int>, "");
|
||||
|
||||
static_assert(!std::__libcpp_is_trivially_equality_comparable<float, float>::value, "");
|
||||
static_assert(!std::__libcpp_is_trivially_equality_comparable<double, double>::value, "");
|
||||
static_assert(!std::__libcpp_is_trivially_equality_comparable<long double, long double>::value, "");
|
||||
static_assert(!std::__is_trivially_equality_comparable_v<float, float>, "");
|
||||
static_assert(!std::__is_trivially_equality_comparable_v<double, double>, "");
|
||||
static_assert(!std::__is_trivially_equality_comparable_v<long double, long double>, "");
|
||||
|
||||
static_assert(std::__libcpp_is_trivially_equality_comparable<
|
||||
static_assert(std::__is_trivially_equality_comparable_v<
|
||||
char,
|
||||
typename std::conditional<std::is_signed<char>::value, signed char, unsigned char>::type>::value,
|
||||
typename std::conditional<std::is_signed<char>::value, signed char, unsigned char>::type>,
|
||||
"");
|
||||
static_assert(std::__libcpp_is_trivially_equality_comparable<char16_t, std::uint_least16_t>::value, "");
|
||||
static_assert(std::__is_trivially_equality_comparable_v<char16_t, std::uint_least16_t>, "");
|
||||
|
||||
struct S {
|
||||
char c;
|
||||
@ -58,8 +58,8 @@ struct S2 {
|
||||
struct VirtualBase : virtual S {};
|
||||
struct NonVirtualBase : S, S2 {};
|
||||
|
||||
static_assert(!std::__libcpp_is_trivially_equality_comparable<S*, VirtualBase*>::value, "");
|
||||
static_assert(!std::__libcpp_is_trivially_equality_comparable<S2*, VirtualBase*>::value, "");
|
||||
static_assert(!std::__is_trivially_equality_comparable_v<S*, VirtualBase*>, "");
|
||||
static_assert(!std::__is_trivially_equality_comparable_v<S2*, VirtualBase*>, "");
|
||||
|
||||
// This is trivially_equality_comparable, but we can't detect it currently
|
||||
static_assert(!std::__libcpp_is_trivially_equality_comparable<S*, NonVirtualBase*>::value, "");
|
||||
static_assert(!std::__is_trivially_equality_comparable_v<S*, NonVirtualBase*>, "");
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user