From 5fecf31c6f9f6f3f778ac6db8c532a069636d708 Mon Sep 17 00:00:00 2001 From: Pierre Fouilloux Date: Thu, 11 Sep 2025 21:04:16 +0800 Subject: [PATCH 1/2] Introduce the UnsignedAbs trait to support the unsigned_abs method on signed integers. --- src/lib.rs | 2 +- src/sign.rs | 42 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index 43212c77..425568af 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -47,7 +47,7 @@ pub use crate::ops::wrapping::{ WrappingAdd, WrappingMul, WrappingNeg, WrappingShl, WrappingShr, WrappingSub, }; pub use crate::pow::{checked_pow, pow, Pow}; -pub use crate::sign::{abs, abs_sub, signum, Signed, Unsigned}; +pub use crate::sign::{abs, abs_sub, signum, Signed, Unsigned, UnsignedAbs}; #[macro_use] mod macros; diff --git a/src/sign.rs b/src/sign.rs index a0d6b0fd..66fe217f 100644 --- a/src/sign.rs +++ b/src/sign.rs @@ -214,3 +214,45 @@ fn signed_wrapping_is_signed() { fn require_signed(_: &T) {} require_signed(&Wrapping(-42)); } + +/// A trait for values which can be converted to an unsigned type with the unsigned_abs utility method. +pub trait UnsignedAbs { + type Unsigned; + + fn unsigned_abs(&self) -> Self::Unsigned; +} + +macro_rules! unsigned_abs_impl { + ($($t:ty:$ut:ty),*) => ($( + impl UnsignedAbs for $t { + type Unsigned = $ut; + + #[inline(always)] + fn unsigned_abs(&self) -> Self::Unsigned { + <$t>::unsigned_abs(*self) + } + } + )*) +} + +unsigned_abs_impl!(i8:u8, i16:u16, i32:u32, i64:u64, i128:u128, isize:usize); + +#[test] +fn unsigned_abs_test() { + fn require_unsigned_abs(_: &T) {} + + require_unsigned_abs(&-42_i8); + require_unsigned_abs(&-42_i16); + require_unsigned_abs(&-42_i32); + require_unsigned_abs(&-42_i64); + require_unsigned_abs(&-42_i128); + require_unsigned_abs(&-42_isize); + + assert_eq!((-42_i8).unsigned_abs(), 42_u8); + assert_eq!(42_i8.unsigned_abs(), 42_u8); + assert_eq!(i8::MIN.unsigned_abs(), 128_u8); + + assert_eq!((-42_i32).unsigned_abs(), 42_u32); + assert_eq!(42_i32.unsigned_abs(), 42_u32); + assert_eq!(i32::MIN.unsigned_abs(), 2147483648_u32); +} From 5b3d4f736c856fe7b341859e94ea7210c0fcc5eb Mon Sep 17 00:00:00 2001 From: Pierre Fouilloux Date: Fri, 12 Sep 2025 18:28:12 +0800 Subject: [PATCH 2/2] Add type constraint to the Unsigned inner type of UnsignedAbs --- src/sign.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sign.rs b/src/sign.rs index 66fe217f..9f8840c0 100644 --- a/src/sign.rs +++ b/src/sign.rs @@ -2,7 +2,7 @@ use core::num::Wrapping; use core::ops::Neg; use crate::float::FloatCore; -use crate::Num; +use crate::{Num, PrimInt}; /// Useful functions for signed numbers (i.e. numbers that can be negative). pub trait Signed: Sized + Num + Neg { @@ -217,7 +217,7 @@ fn signed_wrapping_is_signed() { /// A trait for values which can be converted to an unsigned type with the unsigned_abs utility method. pub trait UnsignedAbs { - type Unsigned; + type Unsigned: PrimInt + Unsigned; fn unsigned_abs(&self) -> Self::Unsigned; }