Skip to content

[libc++] Extend is_trivially_equality_comparable to integral types with the same signedness and size #70344

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
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
11 changes: 10 additions & 1 deletion libcxx/include/__type_traits/is_equality_comparable.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,11 @@
#define _LIBCPP___TYPE_TRAITS_IS_EQUALITY_COMPARABLE_H

#include <__config>
#include <__type_traits/enable_if.h>
#include <__type_traits/integral_constant.h>
#include <__type_traits/is_integral.h>
#include <__type_traits/is_same.h>
#include <__type_traits/is_signed.h>
#include <__type_traits/is_void.h>
#include <__type_traits/remove_cv.h>
#include <__type_traits/remove_cvref.h>
Expand Down Expand Up @@ -44,7 +46,7 @@ struct __is_equality_comparable<_Tp, _Up, __void_t<decltype(std::declval<_Tp>()
// but don't have the same bit-pattern. An exception to this is comparing to a void-pointer. There the bit-pattern is
// always compared.

template <class _Tp, class _Up>
template <class _Tp, class _Up, class = void>
struct __libcpp_is_trivially_equality_comparable_impl : false_type {};

template <class _Tp>
Expand All @@ -57,6 +59,13 @@ struct __libcpp_is_trivially_equality_comparable_impl<_Tp, _Tp>
};
#endif // __has_builtin(__is_trivially_equality_comparable)

template <class _Tp, class _Up>
struct __libcpp_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 {};

template <class _Tp>
struct __libcpp_is_trivially_equality_comparable_impl<_Tp*, _Tp*> : true_type {};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@
//
//===----------------------------------------------------------------------===//

#include <__type_traits/conditional.h>
#include <__type_traits/is_equality_comparable.h>
#include <__type_traits/is_signed.h>
#include <cstdint>

enum Enum : int {};
enum class EnumClass : int {};
Expand All @@ -19,8 +22,8 @@ static_assert(std::__libcpp_is_trivially_equality_comparable<unsigned int, unsig
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::__libcpp_is_trivially_equality_comparable<long, int>::value, "");
static_assert(!std::__libcpp_is_trivially_equality_comparable<int, long>::value, "");
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::__libcpp_is_trivially_equality_comparable<int*, int*>::value, "");
static_assert(std::__libcpp_is_trivially_equality_comparable<int*, void*>::value, "");
Expand All @@ -38,6 +41,12 @@ static_assert(!std::__libcpp_is_trivially_equality_comparable<float, float>::val
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::__libcpp_is_trivially_equality_comparable<
char,
typename std::conditional<std::is_signed<char>::value, signed char, unsigned char>::type>::value,
"");
static_assert(std::__libcpp_is_trivially_equality_comparable<char16_t, std::uint_least16_t>::value, "");

struct S {
char c;
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@
// constexpr bool // constexpr after c++17
// equal(Iter1 first1, Iter1 last1, Iter2 first2, Iter2 last2);

// We test the cartesian product, so we somethimes compare differently signed types
// ADDITIONAL_COMPILE_FLAGS: -Wno-sign-compare

#include <algorithm>
#include <cassert>
#include <functional>
Expand Down Expand Up @@ -131,12 +134,30 @@ TEST_CONSTEXPR_CXX20 bool test() {
struct Base {};
struct Derived : virtual Base {};

struct TestTypes {
template <class T>
struct Test {
template <class U>
void operator()() {
T a[] = {1, 2, 3, 4, 5, 6};
U b[] = {1, 2, 3, 4, 5, 6};
assert(std::equal(a, a + 6, b));
}
};

template <class T>
void operator()() {
types::for_each(types::integer_types(), Test<T>());
}
};

int main(int, char**) {
test();
#if TEST_STD_VER >= 20
static_assert(test());
#endif

types::for_each(types::integer_types(), TestTypes());
types::for_each(types::as_pointers<types::cv_qualified_versions<int> >(),
TestIter2<int, types::as_pointers<types::cv_qualified_versions<int> > >());
types::for_each(types::as_pointers<types::cv_qualified_versions<char> >(),
Expand Down