pub trait IntOperand: Copy {
fn to_u128(self) -> u128;
}
impl IntOperand for u8 {
#[inline]
fn to_u128(self) -> u128 {
u128::from(self)
}
}
impl IntOperand for &u8 {
#[inline]
fn to_u128(self) -> u128 {
u128::from(*self)
}
}
impl IntOperand for u16 {
#[inline]
fn to_u128(self) -> u128 {
u128::from(self)
}
}
impl IntOperand for &u16 {
#[inline]
fn to_u128(self) -> u128 {
u128::from(*self)
}
}
impl IntOperand for u32 {
#[inline]
fn to_u128(self) -> u128 {
u128::from(self)
}
}
impl IntOperand for &u32 {
#[inline]
fn to_u128(self) -> u128 {
u128::from(*self)
}
}
impl IntOperand for u64 {
#[inline]
fn to_u128(self) -> u128 {
u128::from(self)
}
}
impl IntOperand for &u64 {
#[inline]
fn to_u128(self) -> u128 {
u128::from(*self)
}
}
impl IntOperand for u128 {
#[inline]
fn to_u128(self) -> u128 {
self
}
}
impl IntOperand for &u128 {
#[inline]
fn to_u128(self) -> u128 {
*self
}
}
impl IntOperand for usize {
#[inline]
#[allow(clippy::cast_lossless)]
fn to_u128(self) -> u128 {
self as u128
}
}
impl IntOperand for &usize {
#[inline]
#[allow(clippy::cast_lossless)]
fn to_u128(self) -> u128 {
*self as u128
}
}
impl IntOperand for i8 {
#[inline]
fn to_u128(self) -> u128 {
i128::from(self).cast_unsigned()
}
}
impl IntOperand for &i8 {
#[inline]
fn to_u128(self) -> u128 {
i128::from(*self).cast_unsigned()
}
}
impl IntOperand for i16 {
#[inline]
fn to_u128(self) -> u128 {
i128::from(self).cast_unsigned()
}
}
impl IntOperand for &i16 {
#[inline]
fn to_u128(self) -> u128 {
i128::from(*self).cast_unsigned()
}
}
impl IntOperand for i32 {
#[inline]
fn to_u128(self) -> u128 {
i128::from(self).cast_unsigned()
}
}
impl IntOperand for &i32 {
#[inline]
fn to_u128(self) -> u128 {
i128::from(*self).cast_unsigned()
}
}
impl IntOperand for i64 {
#[inline]
fn to_u128(self) -> u128 {
i128::from(self).cast_unsigned()
}
}
impl IntOperand for &i64 {
#[inline]
fn to_u128(self) -> u128 {
i128::from(*self).cast_unsigned()
}
}
impl IntOperand for i128 {
#[inline]
fn to_u128(self) -> u128 {
self.cast_unsigned()
}
}
impl IntOperand for &i128 {
#[inline]
fn to_u128(self) -> u128 {
(*self).cast_unsigned()
}
}
impl IntOperand for isize {
#[inline]
#[allow(clippy::cast_lossless)]
fn to_u128(self) -> u128 {
(self as i128).cast_unsigned()
}
}
impl IntOperand for &isize {
#[inline]
#[allow(clippy::cast_lossless)]
fn to_u128(self) -> u128 {
(*self as i128).cast_unsigned()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn u8_zero_extends() {
assert_eq!(0u8.to_u128(), 0);
assert_eq!(1u8.to_u128(), 1);
assert_eq!(u8::MAX.to_u128(), 255);
}
#[test]
fn u16_zero_extends() {
assert_eq!(0u16.to_u128(), 0);
assert_eq!(u16::MAX.to_u128(), 65535);
}
#[test]
fn u32_zero_extends() {
assert_eq!(0u32.to_u128(), 0);
assert_eq!(u32::MAX.to_u128(), u128::from(u32::MAX));
}
#[test]
fn u64_zero_extends() {
assert_eq!(0u64.to_u128(), 0);
assert_eq!(u64::MAX.to_u128(), u128::from(u64::MAX));
}
#[test]
fn u128_identity() {
assert_eq!(0u128.to_u128(), 0);
assert_eq!(u128::MAX.to_u128(), u128::MAX);
assert_eq!(0x0123_4567_89ab_cdef_u128.to_u128(), 0x0123_4567_89ab_cdef);
}
#[test]
fn usize_zero_extends() {
assert_eq!(0usize.to_u128(), 0);
assert_eq!(1usize.to_u128(), 1);
}
#[test]
fn i8_positive_zero_extends() {
assert_eq!(0i8.to_u128(), 0);
assert_eq!(1i8.to_u128(), 1);
assert_eq!(i8::MAX.to_u128(), 127);
}
#[test]
fn i8_negative_sign_extends() {
assert_eq!((-1i8).to_u128(), u128::MAX);
assert_eq!((-2i8).to_u128(), u128::MAX - 1);
assert_eq!(i8::MIN.to_u128(), (-128i128).to_u128());
}
#[test]
fn i16_positive_zero_extends() {
assert_eq!(0i16.to_u128(), 0);
assert_eq!(i16::MAX.to_u128(), 32767);
}
#[test]
fn i16_negative_sign_extends() {
assert_eq!((-1i16).to_u128(), u128::MAX);
assert_eq!(i16::MIN.to_u128(), i128::from(i16::MIN).to_u128());
}
#[test]
fn i32_positive_zero_extends() {
assert_eq!(0i32.to_u128(), 0);
assert_eq!(i32::MAX.to_u128(), (i32::MAX as u128).to_u128());
}
#[test]
fn i32_negative_sign_extends() {
assert_eq!((-1i32).to_u128(), u128::MAX);
assert_eq!(i32::MIN.to_u128(), i128::from(i32::MIN).to_u128());
}
#[test]
fn i64_positive_zero_extends() {
assert_eq!(0i64.to_u128(), 0);
assert_eq!(i64::MAX.to_u128(), (i64::MAX as u128).to_u128());
}
#[test]
fn i64_negative_sign_extends() {
assert_eq!((-1i64).to_u128(), u128::MAX);
assert_eq!(i64::MIN.to_u128(), i128::from(i64::MIN).to_u128());
}
#[test]
fn i128_positive() {
assert_eq!(0i128.to_u128(), 0);
assert_eq!(1i128.to_u128(), 1);
assert_eq!(i128::MAX.to_u128(), (i128::MAX as u128).to_u128());
}
#[test]
fn i128_negative() {
assert_eq!((-1i128).to_u128(), u128::MAX);
assert_eq!(i128::MIN.to_u128(), i128::MIN.to_u128());
}
#[test]
fn isize_positive() {
assert_eq!(0isize.to_u128(), 0);
assert_eq!(1isize.to_u128(), 1);
}
#[test]
fn isize_negative() {
assert_eq!((-1isize).to_u128(), u128::MAX);
}
#[test]
fn reference_variants_match_owned() {
let u = 42u32;
assert_eq!(u.to_u128(), (&u).to_u128());
let i = -42i32;
assert_eq!(i.to_u128(), (&i).to_u128());
let big = u128::MAX;
assert_eq!(big.to_u128(), (&big).to_u128());
}
#[test]
fn sign_extension_fills_all_high_bits() {
assert_eq!((-1i8).to_u128(), u128::MAX);
assert_eq!((-1i16).to_u128(), u128::MAX);
assert_eq!((-1i32).to_u128(), u128::MAX);
assert_eq!((-1i64).to_u128(), u128::MAX);
assert_eq!((-1i128).to_u128(), u128::MAX);
assert_eq!((-1isize).to_u128(), u128::MAX);
}
#[test]
fn sign_extension_preserves_two_complement_identity() {
for v in [i8::MIN, -42i8, -1i8, 0i8, 1i8, 42i8, i8::MAX] {
assert_eq!(v.to_u128(), i128::from(v).to_u128());
}
}
}