Skip to content

Commit d98f191

Browse files
committed
[libc++] std::cmp_less and other integer comparison functions could be improved
1 parent a100f63 commit d98f191

File tree

1 file changed

+14
-2
lines changed
  • libcxx/include/__utility

1 file changed

+14
-2
lines changed

libcxx/include/__utility/cmp.h

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,13 @@ _LIBCPP_BEGIN_NAMESPACE_STD
2828

2929
template <__signed_or_unsigned_integer _Tp, __signed_or_unsigned_integer _Up>
3030
_LIBCPP_HIDE_FROM_ABI constexpr bool cmp_equal(_Tp __t, _Up __u) noexcept {
31-
if constexpr (is_signed_v<_Tp> == is_signed_v<_Up>)
31+
if constexpr (sizeof(_Tp) < sizeof(int) && sizeof(_Up) < sizeof(int)) {
32+
__builtin_assume(__t < numeric_limits<int>::max() && __u < numeric_limits<int>::max());
33+
return static_cast<int>(__t) == static_cast<int>(__u);
34+
} else if constexpr (sizeof(_Tp) < sizeof(long long) && sizeof(_Up) < sizeof(long long)) {
35+
__builtin_assume(__t < numeric_limits<long long>::max() && __u < numeric_limits<long long>::max());
36+
return static_cast<long long>(__t) == static_cast<long long>(__u);
37+
} else if constexpr (is_signed_v<_Tp> == is_signed_v<_Up>)
3238
return __t == __u;
3339
else if constexpr (is_signed_v<_Tp>)
3440
return __t < 0 ? false : make_unsigned_t<_Tp>(__t) == __u;
@@ -43,7 +49,13 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool cmp_not_equal(_Tp __t, _Up __u) noexcept {
4349

4450
template <__signed_or_unsigned_integer _Tp, __signed_or_unsigned_integer _Up>
4551
_LIBCPP_HIDE_FROM_ABI constexpr bool cmp_less(_Tp __t, _Up __u) noexcept {
46-
if constexpr (is_signed_v<_Tp> == is_signed_v<_Up>)
52+
if constexpr (sizeof(_Tp) < sizeof(int) && sizeof(_Up) < sizeof(int)) {
53+
__builtin_assume(__t < numeric_limits<int>::max() && __u < numeric_limits<int>::max());
54+
return static_cast<int>(__t) < static_cast<int>(__u);
55+
} else if constexpr (sizeof(_Tp) < sizeof(long long) && sizeof(_Up) < sizeof(long long)) {
56+
__builtin_assume(__t < numeric_limits<long long>::max() && __u < numeric_limits<long long>::max());
57+
return static_cast<long long>(__t) < static_cast<long long>(__u);
58+
} else if constexpr (is_signed_v<_Tp> == is_signed_v<_Up>)
4759
return __t < __u;
4860
else if constexpr (is_signed_v<_Tp>)
4961
return __t < 0 ? true : make_unsigned_t<_Tp>(__t) < __u;

0 commit comments

Comments
 (0)