From 79c47d238000e125fc9a522ec4e634ae8cd06861 Mon Sep 17 00:00:00 2001 From: Michael McConville Date: Thu, 24 Dec 2015 22:28:41 -0500 Subject: [PATCH 1/3] Implement arithmetic assignment ops for Wrapping I was surprised to see that these didn't already exist. You need #![feature(augmented_assignments)] to use them. I'm suspect that some attributes need to be added inline, but I'm not sure where. Suggestions welcome. --- src/libcore/num/wrapping.rs | 84 +++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) diff --git a/src/libcore/num/wrapping.rs b/src/libcore/num/wrapping.rs index a7d5fcafd5603..1bc0036a8c4f4 100644 --- a/src/libcore/num/wrapping.rs +++ b/src/libcore/num/wrapping.rs @@ -157,11 +157,95 @@ macro_rules! wrapping_impl { Wrapping(self.0 & other.0) } } + + impl AddAssign for Wrapping<$t> { + fn add_assign(&mut self, other: Wrapping<$t>) { + *self = *self + other; + } + } + + impl SubAssign for Wrapping<$t> { + fn sub_assign(&mut self, other: Wrapping<$t>) { + *self = *self - other; + } + } + + impl MulAssign for Wrapping<$t> { + fn mul_assign(&mut self, other: Wrapping<$t>) { + *self = *self * other; + } + } + + impl DivAssign for Wrapping<$t> { + fn div_assign(&mut self, other: Wrapping<$t>) { + *self = *self / other; + } + } + + /* + impl RemAssign for Wrapping<$t> { + fn rem_assign(&mut self, other: Wrapping<$t>) { + *self = *self % other; + } + } + */ + + impl BitAndAssign for Wrapping<$t> { + fn bitand_assign(&mut self, other: Wrapping<$t>) { + *self = *self & other; + } + } + + impl BitOrAssign for Wrapping<$t> { + fn bitor_assign(&mut self, other: Wrapping<$t>) { + *self = *self | other; + } + } + + impl BitXorAssign for Wrapping<$t> { + fn bitxor_assign(&mut self, other: Wrapping<$t>) { + *self = *self ^ other; + } + } )*) } wrapping_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 } + +macro_rules! wrapping_impl_all { + ($($t:ty)*) => ($( + impl ShlAssign<$f> for Wrapping<$t> { + fn shl_assign(&mut self, other: $f) { + *self = *self << other; + } + } + + impl ShrAssign<$f> for Wrapping<$t> { + fn shr_assign(&mut self, other: $f) { + *self = *self >> other; + } + } + )*) +} + +// FIXME (#23545): uncomment the remaining impls +macro_rules! sh_impl_all { + ($($t:ty)*) => ($( + // sh_impl! { $t, u8 } + // sh_impl! { $t, u16 } + // sh_impl! { $t, u32 } + // sh_impl! { $t, u64 } + sh_impl! { $t, usize } + + // sh_impl! { $t, i8 } + // sh_impl! { $t, i16 } + // sh_impl! { $t, i32 } + // sh_impl! { $t, i64 } + // sh_impl! { $t, isize } + )*) +} + mod shift_max { #![allow(non_upper_case_globals)] From 0794a09a4687a4cac48b09959412883c785dc70f Mon Sep 17 00:00:00 2001 From: Michael McConville Date: Thu, 24 Dec 2015 22:48:10 -0500 Subject: [PATCH 2/3] Fix shift assignment operators for Wrapping --- src/libcore/num/wrapping.rs | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/src/libcore/num/wrapping.rs b/src/libcore/num/wrapping.rs index 1bc0036a8c4f4..70489468a20b2 100644 --- a/src/libcore/num/wrapping.rs +++ b/src/libcore/num/wrapping.rs @@ -212,9 +212,8 @@ macro_rules! wrapping_impl { wrapping_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 } - -macro_rules! wrapping_impl_all { - ($($t:ty)*) => ($( +macro_rules! wrapping_sh_impl { + ($($t:ty, $f:ty)*) => ($( impl ShlAssign<$f> for Wrapping<$t> { fn shl_assign(&mut self, other: $f) { *self = *self << other; @@ -230,22 +229,24 @@ macro_rules! wrapping_impl_all { } // FIXME (#23545): uncomment the remaining impls -macro_rules! sh_impl_all { +macro_rules! wrapping_sh_impl_all { ($($t:ty)*) => ($( - // sh_impl! { $t, u8 } - // sh_impl! { $t, u16 } - // sh_impl! { $t, u32 } - // sh_impl! { $t, u64 } - sh_impl! { $t, usize } - - // sh_impl! { $t, i8 } - // sh_impl! { $t, i16 } - // sh_impl! { $t, i32 } - // sh_impl! { $t, i64 } - // sh_impl! { $t, isize } + // wrapping_sh_impl! { $t, u8 } + // wrapping_sh_impl! { $t, u16 } + // wrapping_sh_impl! { $t, u32 } + // wrapping_sh_impl! { $t, u64 } + wrapping_sh_impl! { $t, usize } + + // wrapping_sh_impl! { $t, i8 } + // wrapping_sh_impl! { $t, i16 } + // wrapping_sh_impl! { $t, i32 } + // wrapping_sh_impl! { $t, i64 } + // wrapping_sh_impl! { $t, isize } )*) } +wrapping_sh_impl_all! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 } + mod shift_max { #![allow(non_upper_case_globals)] From 8368200912614d76b77fcfb6393c07b94a97e331 Mon Sep 17 00:00:00 2001 From: Michael McConville Date: Thu, 24 Dec 2015 23:05:46 -0500 Subject: [PATCH 3/3] Add #[inline(always)] to assignment operator impls Pointed out by Steven Fackler. --- src/libcore/num/wrapping.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/libcore/num/wrapping.rs b/src/libcore/num/wrapping.rs index 70489468a20b2..27846cba2c9d3 100644 --- a/src/libcore/num/wrapping.rs +++ b/src/libcore/num/wrapping.rs @@ -159,24 +159,28 @@ macro_rules! wrapping_impl { } impl AddAssign for Wrapping<$t> { + #[inline(always)] fn add_assign(&mut self, other: Wrapping<$t>) { *self = *self + other; } } impl SubAssign for Wrapping<$t> { + #[inline(always)] fn sub_assign(&mut self, other: Wrapping<$t>) { *self = *self - other; } } impl MulAssign for Wrapping<$t> { + #[inline(always)] fn mul_assign(&mut self, other: Wrapping<$t>) { *self = *self * other; } } impl DivAssign for Wrapping<$t> { + #[inline(always)] fn div_assign(&mut self, other: Wrapping<$t>) { *self = *self / other; } @@ -184,6 +188,7 @@ macro_rules! wrapping_impl { /* impl RemAssign for Wrapping<$t> { + #[inline(always)] fn rem_assign(&mut self, other: Wrapping<$t>) { *self = *self % other; } @@ -191,18 +196,21 @@ macro_rules! wrapping_impl { */ impl BitAndAssign for Wrapping<$t> { + #[inline(always)] fn bitand_assign(&mut self, other: Wrapping<$t>) { *self = *self & other; } } impl BitOrAssign for Wrapping<$t> { + #[inline(always)] fn bitor_assign(&mut self, other: Wrapping<$t>) { *self = *self | other; } } impl BitXorAssign for Wrapping<$t> { + #[inline(always)] fn bitxor_assign(&mut self, other: Wrapping<$t>) { *self = *self ^ other; } @@ -215,12 +223,14 @@ wrapping_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 } macro_rules! wrapping_sh_impl { ($($t:ty, $f:ty)*) => ($( impl ShlAssign<$f> for Wrapping<$t> { + #[inline(always)] fn shl_assign(&mut self, other: $f) { *self = *self << other; } } impl ShrAssign<$f> for Wrapping<$t> { + #[inline(always)] fn shr_assign(&mut self, other: $f) { *self = *self >> other; }