-
Notifications
You must be signed in to change notification settings - Fork 15.2k
Description
| Bugzilla Link | 51083 |
| Version | unspecified |
| OS | All |
| CC | @mclow |
Extended Description
std::is_integral, std::is_signed, std::is_unsigned, std::integral, std::unsigned_integral all work for _ExtInt types, because they use compiler intrinsics.
But std::make_signed and std::make_unsigned are implemented directly in libc++ via a hard-coded list of remappings instead. They end up (approximately) using the rules for enum types and character types, picking the lowest rank standard integer type with the same size as the given type. This, for example, picks signed char when given unsigned _ExtInt(3) and fails when given unsigned _ExtInt(129).
That seems like the wrong outcome to me, and is inconsistent with the behavior of std::is_signed and friends. I think make_[un]signed should treat _ExtInt as being a signed integer type and should treat unsigned _ExtInt as being an unsigned integer type, so make_signed_t<unsigned _ExtInt(N)> should yield _ExtInt(N) and symmetrically for make_unsigned_t.
Presumably we should add compiler intrinsics __make_signed and __make_unsigned and use them from libc++ so that extended integer types can be made to behave properly.