From d798bd4fb8a26719543da03ae845492a4460391d Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Wed, 27 Jan 2016 23:30:33 -0800 Subject: [PATCH 1/2] Add arithmetic/logical shifts to PrimInt --- src/traits.rs | 100 ++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 97 insertions(+), 3 deletions(-) diff --git a/src/traits.rs b/src/traits.rs index 3397018..5bf63da 100644 --- a/src/traits.rs +++ b/src/traits.rs @@ -742,6 +742,74 @@ pub trait PrimInt /// ``` fn rotate_right(self, n: u32) -> Self; + /// Shifts the bits to the left by a specified amount amount, `n`, filling + /// zeros in the least significant bits. + /// + /// This is bitwise equivalent to signed `Shl`. + /// + /// # Examples + /// + /// ``` + /// use num::traits::PrimInt; + /// + /// let n = 0x0123456789ABCDEFu64; + /// let m = 0x3456789ABCDEF000u64; + /// + /// assert_eq!(n.arithmetic_shl(12), m); + /// ``` + fn arithmetic_shl(self, n: u32) -> Self; + + /// Shifts the bits to the right by a specified amount amount, `n`, copying + /// the "sign bit" in the most significant bits even for unsigned types. + /// + /// This is bitwise equivalent to signed `Shr`. + /// + /// # Examples + /// + /// ``` + /// use num::traits::PrimInt; + /// + /// let n = 0xFEDCBA9876543210u64; + /// let m = 0xFFFFEDCBA9876543u64; + /// + /// assert_eq!(n.arithmetic_shr(12), m); + /// ``` + fn arithmetic_shr(self, n: u32) -> Self; + + /// Shifts the bits to the left by a specified amount amount, `n`, filling + /// zeros in the least significant bits. + /// + /// This is bitwise equivalent to unsigned `Shl`. + /// + /// # Examples + /// + /// ``` + /// use num::traits::PrimInt; + /// + /// let n = 0x0123456789ABCDEFi64; + /// let m = 0x3456789ABCDEF000i64; + /// + /// assert_eq!(n.logical_shl(12), m); + /// ``` + fn logical_shl(self, n: u32) -> Self; + + /// Shifts the bits to the right by a specified amount amount, `n`, filling + /// zeros in the most significant bits. + /// + /// This is bitwise equivalent to unsigned `Shr`. + /// + /// # Examples + /// + /// ``` + /// use num::traits::PrimInt; + /// + /// let n = 0xFEDCBA9876543210i64; + /// let m = 0x000FEDCBA9876543i64; + /// + /// assert_eq!(n.logical_shr(12), m); + /// ``` + fn logical_shr(self, n: u32) -> Self; + /// Reverses the byte order of the integer. /// /// # Examples @@ -845,7 +913,7 @@ pub trait PrimInt } macro_rules! prim_int_impl { - ($($T:ty)*) => ($( + ($T:ty, $S:ty, $U:ty) => ( impl PrimInt for $T { fn count_ones(self) -> u32 { <$T>::count_ones(self) @@ -871,6 +939,22 @@ macro_rules! prim_int_impl { <$T>::rotate_right(self, n) } + fn arithmetic_shl(self, n: u32) -> Self { + ((self as $S) << n) as $T + } + + fn arithmetic_shr(self, n: u32) -> Self { + ((self as $S) >> n) as $T + } + + fn logical_shl(self, n: u32) -> Self { + ((self as $U) << n) as $T + } + + fn logical_shr(self, n: u32) -> Self { + ((self as $U) >> n) as $T + } + fn swap_bytes(self) -> Self { <$T>::swap_bytes(self) } @@ -895,10 +979,20 @@ macro_rules! prim_int_impl { <$T>::pow(self, exp) } } - )*) + ) } -prim_int_impl!(u8 u16 u32 u64 usize i8 i16 i32 i64 isize); +// prim_int_impl!(type, signed, unsigned); +prim_int_impl!(u8, i8, u8); +prim_int_impl!(u16, i16, u16); +prim_int_impl!(u32, i32, u32); +prim_int_impl!(u64, i64, u64); +prim_int_impl!(usize, isize, usize); +prim_int_impl!(i8, i8, u8); +prim_int_impl!(i16, i16, u16); +prim_int_impl!(i32, i32, u32); +prim_int_impl!(i64, i64, u64); +prim_int_impl!(isize, isize, usize); /// A generic trait for converting a value to a number. pub trait ToPrimitive { From afee4e4662f4a6e0d4ed9cb4e3396726c36d1b60 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Thu, 28 Jan 2016 22:37:18 -0800 Subject: [PATCH 2/2] Change PrimInt shift names to signed/unsigned --- src/traits.rs | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/traits.rs b/src/traits.rs index 5bf63da..5b01b39 100644 --- a/src/traits.rs +++ b/src/traits.rs @@ -755,9 +755,9 @@ pub trait PrimInt /// let n = 0x0123456789ABCDEFu64; /// let m = 0x3456789ABCDEF000u64; /// - /// assert_eq!(n.arithmetic_shl(12), m); + /// assert_eq!(n.signed_shl(12), m); /// ``` - fn arithmetic_shl(self, n: u32) -> Self; + fn signed_shl(self, n: u32) -> Self; /// Shifts the bits to the right by a specified amount amount, `n`, copying /// the "sign bit" in the most significant bits even for unsigned types. @@ -772,9 +772,9 @@ pub trait PrimInt /// let n = 0xFEDCBA9876543210u64; /// let m = 0xFFFFEDCBA9876543u64; /// - /// assert_eq!(n.arithmetic_shr(12), m); + /// assert_eq!(n.signed_shr(12), m); /// ``` - fn arithmetic_shr(self, n: u32) -> Self; + fn signed_shr(self, n: u32) -> Self; /// Shifts the bits to the left by a specified amount amount, `n`, filling /// zeros in the least significant bits. @@ -789,9 +789,9 @@ pub trait PrimInt /// let n = 0x0123456789ABCDEFi64; /// let m = 0x3456789ABCDEF000i64; /// - /// assert_eq!(n.logical_shl(12), m); + /// assert_eq!(n.unsigned_shl(12), m); /// ``` - fn logical_shl(self, n: u32) -> Self; + fn unsigned_shl(self, n: u32) -> Self; /// Shifts the bits to the right by a specified amount amount, `n`, filling /// zeros in the most significant bits. @@ -806,9 +806,9 @@ pub trait PrimInt /// let n = 0xFEDCBA9876543210i64; /// let m = 0x000FEDCBA9876543i64; /// - /// assert_eq!(n.logical_shr(12), m); + /// assert_eq!(n.unsigned_shr(12), m); /// ``` - fn logical_shr(self, n: u32) -> Self; + fn unsigned_shr(self, n: u32) -> Self; /// Reverses the byte order of the integer. /// @@ -939,19 +939,19 @@ macro_rules! prim_int_impl { <$T>::rotate_right(self, n) } - fn arithmetic_shl(self, n: u32) -> Self { + fn signed_shl(self, n: u32) -> Self { ((self as $S) << n) as $T } - fn arithmetic_shr(self, n: u32) -> Self { + fn signed_shr(self, n: u32) -> Self { ((self as $S) >> n) as $T } - fn logical_shl(self, n: u32) -> Self { + fn unsigned_shl(self, n: u32) -> Self { ((self as $U) << n) as $T } - fn logical_shr(self, n: u32) -> Self { + fn unsigned_shr(self, n: u32) -> Self { ((self as $U) >> n) as $T }