[libcxx-commits] [libcxx] [libc++] std::cmp_less and other integer comparison functions could be improved (PR #151332)

A. Jiang via libcxx-commits libcxx-commits at lists.llvm.org
Fri Aug 8 00:17:05 PDT 2025


================
@@ -28,7 +29,11 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <__signed_or_unsigned_integer _Tp, __signed_or_unsigned_integer _Up>
 _LIBCPP_HIDE_FROM_ABI constexpr bool cmp_equal(_Tp __t, _Up __u) noexcept {
-  if constexpr (is_signed_v<_Tp> == is_signed_v<_Up>)
+  if constexpr (sizeof(_Tp) < sizeof(int) && sizeof(_Up) < sizeof(int))
----------------
frederick-vs-ja wrote:

This doesn't cover comparison between `int` and `unsigned short` yet.

I wonder whether we can/should do the following (ditto `cmp_less`).
```C++
template <class _Tp, class _Ip>
inline constexpr bool __comparison_can_promote_to = false;

template <__signed_or_unsigned_integer _Tp, __signed_integer _Ip>
inline constexpr bool __comparison_can_promote_to =
    __signed_integer<_Tp> ? sizeof(_Tp) <= sizeof(_Ip) : sizeof(_Tp) < sizeof(_Ip);

template <__signed_or_unsigned_integer _Tp, __signed_or_unsigned_integer _Up>
_LIBCPP_HIDE_FROM_ABI constexpr bool cmp_equal(_Tp __t, _Up __u) noexcept {
  if constexpr (is_signed_v<_Tp> == is_signed_v<_Up>)
    return __t == __u;
  else if constexpr (__comparison_can_promote_to<_Tp, int> && __comparison_can_promote_to<_Up, int>)
    return static_cast<int>(__t) == static_cast<int>(__u);
  else if constexpr (__comparison_can_promote_to<_Tp, long long> && __comparison_can_promote_to<_Up, long long>)
    return static_cast<long long>(__t) == static_cast<long long>(__u);
  else if constexpr (is_signed_v<_Tp>)
    return __t < 0 ? false : make_unsigned_t<_Tp>(__t) == __u;
  else
    return __u < 0 ? false : __t == make_unsigned_t<_Up>(__u);
}
```

https://github.com/llvm/llvm-project/pull/151332


More information about the libcxx-commits mailing list