aboutsummaryrefslogtreecommitdiff
path: root/libcxx/include/__utility/cmp.h
diff options
context:
space:
mode:
Diffstat (limited to 'libcxx/include/__utility/cmp.h')
-rw-r--r--libcxx/include/__utility/cmp.h12
1 files changed, 12 insertions, 0 deletions
diff --git a/libcxx/include/__utility/cmp.h b/libcxx/include/__utility/cmp.h
index 14dc0c1..68864e2 100644
--- a/libcxx/include/__utility/cmp.h
+++ b/libcxx/include/__utility/cmp.h
@@ -26,10 +26,18 @@ _LIBCPP_BEGIN_NAMESPACE_STD
#if _LIBCPP_STD_VER >= 20
+template <typename _Tp, typename _Ip>
+concept __comparison_can_promote_to =
+ sizeof(_Tp) < sizeof(_Ip) || (sizeof(_Tp) == sizeof(_Ip) && __signed_integer<_Tp>);
+
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
@@ -45,6 +53,10 @@ template <__signed_or_unsigned_integer _Tp, __signed_or_unsigned_integer _Up>
_LIBCPP_HIDE_FROM_ABI constexpr bool cmp_less(_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 ? true : make_unsigned_t<_Tp>(__t) < __u;
else