Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions libcxx/include/__algorithm/equal.h
Original file line number Diff line number Diff line change
Expand Up @@ -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&) {
Expand Down Expand Up @@ -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&) {
Expand Down
11 changes: 5 additions & 6 deletions libcxx/include/__algorithm/find.h
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down Expand Up @@ -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>
Expand Down
4 changes: 2 additions & 2 deletions libcxx/include/__algorithm/lexicographical_compare.h
Original file line number Diff line number Diff line change
Expand Up @@ -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&) {
Expand Down
2 changes: 1 addition & 1 deletion libcxx/include/__algorithm/mismatch.h
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
7 changes: 3 additions & 4 deletions libcxx/include/__string/constexpr_c_functions.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand All @@ -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()) {
Expand Down
37 changes: 16 additions & 21 deletions libcxx/include/__type_traits/is_equality_comparable.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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

Expand Down
4 changes: 2 additions & 2 deletions libcxx/include/cwchar
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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