diff options
| author | Nicholas Mazzuca <npmazzuca@gmail.com> | 2016-01-01 04:28:26 -0800 |
|---|---|---|
| committer | Nicholas Mazzuca <npmazzuca@gmail.com> | 2016-01-01 04:28:26 -0800 |
| commit | f96243295a297e8e64e0d7cf9c349f69cd7dcc56 (patch) | |
| tree | c7a3a111f19060d1697e943ef781b70bc142814a /src/libcore/num | |
| parent | bfb4212ee2ae658dfd4feb5991ebff55e9ac5240 (diff) | |
| download | rust-f96243295a297e8e64e0d7cf9c349f69cd7dcc56.tar.gz rust-f96243295a297e8e64e0d7cf9c349f69cd7dcc56.zip | |
In the middle of the implementation
Diffstat (limited to 'src/libcore/num')
| -rw-r--r-- | src/libcore/num/wrapping.rs | 524 |
1 files changed, 316 insertions, 208 deletions
diff --git a/src/libcore/num/wrapping.rs b/src/libcore/num/wrapping.rs index a7d5fcafd56..637e99672ae 100644 --- a/src/libcore/num/wrapping.rs +++ b/src/libcore/num/wrapping.rs @@ -12,13 +12,13 @@ #![unstable(feature = "wrapping", reason = "may be removed or relocated", issue = "27755")] -pub use intrinsics::{add_with_overflow, sub_with_overflow, mul_with_overflow}; +use intrinsics::{add_with_overflow, sub_with_overflow, mul_with_overflow}; use super::Wrapping; use ops::*; -use ::{i8,i16,i32,i64}; +use ::{i8, i16, i32, i64, isize}; pub trait OverflowingOps { fn overflowing_add(self, rhs: Self) -> (Self, bool); @@ -33,15 +33,71 @@ pub trait OverflowingOps { fn overflowing_shr(self, rhs: u32) -> (Self, bool); } -macro_rules! sh_impl { - ($t:ty, $f:ty) => ( +macro_rules! sh_impl_signed { + ($t:ident, $f:ident) => ( #[stable(feature = "rust1", since = "1.0.0")] impl Shl<$f> for Wrapping<$t> { type Output = Wrapping<$t>; #[inline(always)] fn shl(self, other: $f) -> Wrapping<$t> { - Wrapping(self.0 << other) + if other < 0 { + Wrapping(self.0 >> (-other & self::shift_max::$t as $f)) + } else { + Wrapping(self.0 << (other & self::shift_max::$t as $f)) + } + } + } + + #[unstable(feature = "wrapping_impls", reason = "recently added", issue = "30524")] + impl ShlAssign<$f> for Wrapping<$t> { + #[inline(always)] + fn shl_assign(&mut self, other: $f) { + *self = *self << other; + } + } + + #[stable(feature = "rust1", since = "1.0.0")] + impl Shr<$f> for Wrapping<$t> { + type Output = Wrapping<$t>; + + #[inline(always)] + fn shr(self, other: $f) -> Wrapping<$t> { + if other < 0 { + Wrapping(self.0 << (-other & self::shift_max::$t as $f)) + } else { + Wrapping(self.0 >> (other & self::shift_max::$t as $f)) + } + } + } + + #[unstable(feature = "wrapping_impls", reason = "recently added", issue = "30524")] + impl ShrAssign<$f> for Wrapping<$t> { + #[inline(always)] + fn shr_assign(&mut self, other: $f) { + *self = *self >> other; + } + } + ) +} + +macro_rules! sh_impl_unsigned { + ($t:ident, $f:ident) => ( + #[stable(feature = "rust1", since = "1.0.0")] + impl Shl<$f> for Wrapping<$t> { + type Output = Wrapping<$t>; + + #[inline(always)] + fn shl(self, other: $f) -> Wrapping<$t> { + Wrapping(self.0 << (other & self::shift_max::$t as $f)) + } + } + + #[unstable(feature = "wrapping_impls", reason = "recently added", issue = "30524")] + impl ShlAssign<$f> for Wrapping<$t> { + #[inline(always)] + fn shl_assign(&mut self, other: $f) { + *self = *self << other; } } @@ -51,7 +107,15 @@ macro_rules! sh_impl { #[inline(always)] fn shr(self, other: $f) -> Wrapping<$t> { - Wrapping(self.0 >> other) + Wrapping(self.0 >> (other & self::shift_max::$t as $f)) + } + } + + #[unstable(feature = "wrapping_impls", reason = "recently added", issue = "30524")] + impl ShrAssign<$f> for Wrapping<$t> { + #[inline(always)] + fn shr_assign(&mut self, other: $f) { + *self = *self >> other; } } ) @@ -59,18 +123,18 @@ macro_rules! sh_impl { // 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 } + ($($t:ident)*) => ($( + sh_impl_unsigned! { $t, u8 } + sh_impl_unsigned! { $t, u16 } + sh_impl_unsigned! { $t, u32 } + sh_impl_unsigned! { $t, u64 } + sh_impl_unsigned! { $t, usize } + + sh_impl_signed! { $t, i8 } + sh_impl_signed! { $t, i16 } + sh_impl_signed! { $t, i32 } + sh_impl_signed! { $t, i64 } + sh_impl_signed! { $t, isize } )*) } @@ -88,6 +152,32 @@ macro_rules! wrapping_impl { } } + #[unstable(feature = "wrapping_impls", reason = "recently added", issue = "30524")] + impl Add<$t> for Wrapping<$t> { + type Output = Wrapping<$t>; + + #[inline(always)] + fn add(self, other: $t) -> Wrapping<$t> { + self + Wrapping(other) + } + } + + #[unstable(feature = "op_assign_traits", reason = "recently added", issue = "28235")] + impl AddAssign for Wrapping<$t> { + #[inline(always)] + fn add_assign(&mut self, other: Wrapping<$t>) { + *self = *self + other; + } + } + + #[unstable(feature = "wrapping_impls", reason = "recently added", issue = "30524")] + impl AddAssign<$t> for Wrapping<$t> { + #[inline(always)] + fn add_assign(&mut self, other: $t) { + self.add_assign(Wrapping(other)) + } + } + #[stable(feature = "rust1", since = "1.0.0")] impl Sub for Wrapping<$t> { type Output = Wrapping<$t>; @@ -98,6 +188,32 @@ macro_rules! wrapping_impl { } } + #[unstable(feature = "wrapping_impls", reason = "recently added", issue = "30524")] + impl Sub<$t> for Wrapping<$t> { + type Output = Wrapping<$t>; + + #[inline(always)] + fn sub(self, other: $t) -> Wrapping<$t> { + self - Wrapping(other) + } + } + + #[unstable(feature = "op_assign_traits", reason = "recently added", issue = "28235")] + impl SubAssign for Wrapping<$t> { + #[inline(always)] + fn sub_assign(&mut self, other: Wrapping<$t>) { + *self = *self - other; + } + } + + #[unstable(feature = "wrapping_impls", reason = "recently added", issue = "30524")] + impl SubAssign<$t> for Wrapping<$t> { + #[inline(always)] + fn sub_assign(&mut self, other: $t) { + self.sub_assign(Wrapping(other)) + } + } + #[stable(feature = "rust1", since = "1.0.0")] impl Mul for Wrapping<$t> { type Output = Wrapping<$t>; @@ -108,6 +224,32 @@ macro_rules! wrapping_impl { } } + #[unstable(feature = "wrapping_impls", reason = "recently added", issue = "30524")] + impl Mul<$t> for Wrapping<$t> { + type Output = Wrapping<$t>; + + #[inline(always)] + fn mul(self, other: $t) -> Wrapping<$t> { + self * Wrapping(other) + } + } + + #[unstable(feature = "op_assign_traits", reason = "recently added", issue = "28235")] + impl MulAssign for Wrapping<$t> { + #[inline(always)] + fn mul_assign(&mut self, other: Wrapping<$t>) { + *self = *self * other; + } + } + + #[unstable(feature = "wrapping_impls", reason = "recently added", issue = "30524")] + impl MulAssign<$t> for Wrapping<$t> { + #[inline(always)] + fn mul_assign(&mut self, other: $t) { + self.mul_assign(Wrapping(other)) + } + } + #[stable(feature = "wrapping_div", since = "1.3.0")] impl Div for Wrapping<$t> { type Output = Wrapping<$t>; @@ -118,6 +260,68 @@ macro_rules! wrapping_impl { } } + #[unstable(feature = "wrapping_impls", reason = "recently added", issue = "30524")] + impl Div<$t> for Wrapping<$t> { + type Output = Wrapping<$t>; + + #[inline(always)] + fn div(self, other: $t) -> Wrapping<$t> { + self / Wrapping(other) + } + } + + #[unstable(feature = "op_assign_traits", reason = "recently added", issue = "28235")] + impl DivAssign for Wrapping<$t> { + #[inline(always)] + fn div_assign(&mut self, other: Wrapping<$t>) { + *self = *self / other; + } + } + + #[unstable(feature = "wrapping_impls", reason = "recently added", issue = "30524")] + impl DivAssign<$t> for Wrapping<$t> { + #[inline(always)] + fn div_assign(&mut self, other: $t) { + self.div_assign(Wrapping(other)) + } + } + + #[unstable(feature = "wrapping_impls", reason = "recently added", issue = "30524")] + impl Rem for Wrapping<$t> { + type Output = Wrapping<$t>; + + #[inline(always)] + fn rem(self, other: Wrapping<$t>) -> Wrapping<$t> { + Wrapping(self.0.wrapping_rem(other.0)) + } + } + + #[unstable(feature = "wrapping_impls", reason = "recently added", issue = "30524")] + impl Rem<$t> for Wrapping<$t> { + type Output = Wrapping<$t>; + + #[inline(always)] + fn rem(self, other: $t) -> Wrapping<$t> { + self % Wrapping(other) + } + } + + #[unstable(feature = "op_assign_traits", reason = "recently added", issue = "28235")] + impl RemAssign for Wrapping<$t> { + #[inline(always)] + fn rem_assign(&mut self, other: Wrapping<$t>) { + *self = *self % other; + } + } + + #[unstable(feature = "wrapping_impls", reason = "recently added", issue = "30524")] + impl RemAssign<$t> for Wrapping<$t> { + #[inline(always)] + fn rem_assign(&mut self, other: $t) { + self.rem_assign(Wrapping(other)) + } + } + #[stable(feature = "rust1", since = "1.0.0")] impl Not for Wrapping<$t> { type Output = Wrapping<$t>; @@ -138,6 +342,32 @@ macro_rules! wrapping_impl { } } + #[unstable(feature = "wrapping_impls", reason = "recently added", issue = "30524")] + impl BitXor<$t> for Wrapping<$t> { + type Output = Wrapping<$t>; + + #[inline(always)] + fn bitxor(self, other: $t) -> Wrapping<$t> { + self ^ Wrapping(other) + } + } + + #[unstable(feature = "op_assign_traits", reason = "recently added", issue = "28235")] + impl BitXorAssign for Wrapping<$t> { + #[inline(always)] + fn bitxor_assign(&mut self, other: Wrapping<$t>) { + *self = *self ^ other; + } + } + + #[unstable(feature = "wrapping_impls", reason = "recently added", issue = "30524")] + impl BitXorAssign<$t> for Wrapping<$t> { + #[inline(always)] + fn bitxor_assign(&mut self, other: $t) { + self.bitxor_assign(Wrapping(other)) + } + } + #[stable(feature = "rust1", since = "1.0.0")] impl BitOr for Wrapping<$t> { type Output = Wrapping<$t>; @@ -148,6 +378,32 @@ macro_rules! wrapping_impl { } } + #[unstable(feature = "wrapping_impls", reason = "recently added", issue = "30524")] + impl BitOr<$t> for Wrapping<$t> { + type Output = Wrapping<$t>; + + #[inline(always)] + fn bitor(self, other: $t) -> Wrapping<$t> { + self | Wrapping(other) + } + } + + #[unstable(feature = "op_assign_traits", reason = "recently added", issue = "28235")] + impl BitOrAssign for Wrapping<$t> { + #[inline(always)] + fn bitor_assign(&mut self, other: Wrapping<$t>) { + *self = *self | other; + } + } + + #[unstable(feature = "wrapping_impls", reason = "recently added", issue = "30524")] + impl BitOrAssign<$t> for Wrapping<$t> { + #[inline(always)] + fn bitor_assign(&mut self, other: $t) { + self.bitor_assign(Wrapping(other)) + } + } + #[stable(feature = "rust1", since = "1.0.0")] impl BitAnd for Wrapping<$t> { type Output = Wrapping<$t>; @@ -157,6 +413,32 @@ macro_rules! wrapping_impl { Wrapping(self.0 & other.0) } } + + #[unstable(feature = "wrapping_impls", reason = "recently added", issue = "30524")] + impl BitAnd<$t> for Wrapping<$t> { + type Output = Wrapping<$t>; + + #[inline(always)] + fn bitand(self, other: $t) -> Wrapping<$t> { + self & Wrapping(other) + } + } + + #[unstable(feature = "op_assign_traits", reason = "recently added", issue = "28235")] + impl BitAndAssign for Wrapping<$t> { + #[inline(always)] + fn bitand_assign(&mut self, other: Wrapping<$t>) { + *self = *self & other; + } + } + + #[unstable(feature = "wrapping_impls", reason = "recently added", issue = "30524")] + impl BitAndAssign<$t> for Wrapping<$t> { + #[inline(always)] + fn bitand_assign(&mut self, other: $t) { + self.bitand_assign(Wrapping(other)) + } + } )*) } @@ -165,15 +447,29 @@ wrapping_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 } mod shift_max { #![allow(non_upper_case_globals)] + #[cfg(target_pointer_width = "32")] + mod platform { + pub const usize: u32 = super::u32; + pub const isize: u32 = super::i32; + } + + #[cfg(target_pointer_width = "64")] + mod platform { + pub const usize: u32 = super::u64; + pub const isize: u32 = super::i64; + } + pub const i8: u32 = (1 << 3) - 1; pub const i16: u32 = (1 << 4) - 1; pub const i32: u32 = (1 << 5) - 1; pub const i64: u32 = (1 << 6) - 1; + pub use self::platform::isize; pub const u8: u32 = i8; pub const u16: u32 = i16; pub const u32: u32 = i32; pub const u64: u32 = i64; + pub use self::platform::usize; } macro_rules! signed_overflowing_impl { @@ -288,193 +584,5 @@ macro_rules! unsigned_overflowing_impl { )*) } -signed_overflowing_impl! { i8 i16 i32 i64 } -unsigned_overflowing_impl! { u8 u16 u32 u64 } - -#[cfg(target_pointer_width = "64")] -impl OverflowingOps for usize { - #[inline(always)] - fn overflowing_add(self, rhs: usize) -> (usize, bool) { - unsafe { - add_with_overflow(self, rhs) - } - } - #[inline(always)] - fn overflowing_sub(self, rhs: usize) -> (usize, bool) { - unsafe { - sub_with_overflow(self, rhs) - } - } - #[inline(always)] - fn overflowing_mul(self, rhs: usize) -> (usize, bool) { - unsafe { - mul_with_overflow(self, rhs) - } - } - #[inline(always)] - fn overflowing_div(self, rhs: usize) -> (usize, bool) { - let (r, f) = (self as u64).overflowing_div(rhs as u64); - (r as usize, f) - } - #[inline(always)] - fn overflowing_rem(self, rhs: usize) -> (usize, bool) { - let (r, f) = (self as u64).overflowing_rem(rhs as u64); - (r as usize, f) - } - #[inline(always)] - fn overflowing_neg(self) -> (usize, bool) { - let (r, f) = (self as u64).overflowing_neg(); - (r as usize, f) - } - #[inline(always)] - fn overflowing_shl(self, rhs: u32) -> (usize, bool) { - let (r, f) = (self as u64).overflowing_shl(rhs); - (r as usize, f) - } - #[inline(always)] - fn overflowing_shr(self, rhs: u32) -> (usize, bool) { - let (r, f) = (self as u64).overflowing_shr(rhs); - (r as usize, f) - } -} - -#[cfg(target_pointer_width = "32")] -impl OverflowingOps for usize { - #[inline(always)] - fn overflowing_add(self, rhs: usize) -> (usize, bool) { - unsafe { - add_with_overflow(self, rhs) - } - } - #[inline(always)] - fn overflowing_sub(self, rhs: usize) -> (usize, bool) { - unsafe { - sub_with_overflow(self, rhs) - } - } - #[inline(always)] - fn overflowing_mul(self, rhs: usize) -> (usize, bool) { - unsafe { - mul_with_overflow(self, rhs) - } - } - #[inline(always)] - fn overflowing_div(self, rhs: usize) -> (usize, bool) { - let (r, f) = (self as u32).overflowing_div(rhs as u32); - (r as usize, f) - } - #[inline(always)] - fn overflowing_rem(self, rhs: usize) -> (usize, bool) { - let (r, f) = (self as u32).overflowing_rem(rhs as u32); - (r as usize, f) - } - #[inline(always)] - fn overflowing_neg(self) -> (usize, bool) { - let (r, f) = (self as u32).overflowing_neg(); - (r as usize, f) - } - #[inline(always)] - fn overflowing_shl(self, rhs: u32) -> (usize, bool) { - let (r, f) = (self as u32).overflowing_shl(rhs); - (r as usize, f) - } - #[inline(always)] - fn overflowing_shr(self, rhs: u32) -> (usize, bool) { - let (r, f) = (self as u32).overflowing_shr(rhs); - (r as usize, f) - } -} - -#[cfg(target_pointer_width = "64")] -impl OverflowingOps for isize { - #[inline(always)] - fn overflowing_add(self, rhs: isize) -> (isize, bool) { - unsafe { - add_with_overflow(self, rhs) - } - } - #[inline(always)] - fn overflowing_sub(self, rhs: isize) -> (isize, bool) { - unsafe { - sub_with_overflow(self, rhs) - } - } - #[inline(always)] - fn overflowing_mul(self, rhs: isize) -> (isize, bool) { - unsafe { - mul_with_overflow(self, rhs) - } - } - #[inline(always)] - fn overflowing_div(self, rhs: isize) -> (isize, bool) { - let (r, f) = (self as i64).overflowing_div(rhs as i64); - (r as isize, f) - } - #[inline(always)] - fn overflowing_rem(self, rhs: isize) -> (isize, bool) { - let (r, f) = (self as i64).overflowing_rem(rhs as i64); - (r as isize, f) - } - #[inline(always)] - fn overflowing_neg(self) -> (isize, bool) { - let (r, f) = (self as i64).overflowing_neg(); - (r as isize, f) - } - #[inline(always)] - fn overflowing_shl(self, rhs: u32) -> (isize, bool) { - let (r, f) = (self as i64).overflowing_shl(rhs); - (r as isize, f) - } - #[inline(always)] - fn overflowing_shr(self, rhs: u32) -> (isize, bool) { - let (r, f) = (self as i64).overflowing_shr(rhs); - (r as isize, f) - } -} - -#[cfg(target_pointer_width = "32")] -impl OverflowingOps for isize { - #[inline(always)] - fn overflowing_add(self, rhs: isize) -> (isize, bool) { - unsafe { - add_with_overflow(self, rhs) - } - } - #[inline(always)] - fn overflowing_sub(self, rhs: isize) -> (isize, bool) { - unsafe { - sub_with_overflow(self, rhs) - } - } - #[inline(always)] - fn overflowing_mul(self, rhs: isize) -> (isize, bool) { - unsafe { - mul_with_overflow(self, rhs) - } - } - #[inline(always)] - fn overflowing_div(self, rhs: isize) -> (isize, bool) { - let (r, f) = (self as i32).overflowing_div(rhs as i32); - (r as isize, f) - } - #[inline(always)] - fn overflowing_rem(self, rhs: isize) -> (isize, bool) { - let (r, f) = (self as i32).overflowing_rem(rhs as i32); - (r as isize, f) - } - #[inline(always)] - fn overflowing_neg(self) -> (isize, bool) { - let (r, f) = (self as i32).overflowing_neg(); - (r as isize, f) - } - #[inline(always)] - fn overflowing_shl(self, rhs: u32) -> (isize, bool) { - let (r, f) = (self as i32).overflowing_shl(rhs); - (r as isize, f) - } - #[inline(always)] - fn overflowing_shr(self, rhs: u32) -> (isize, bool) { - let (r, f) = (self as i32).overflowing_shr(rhs); - (r as isize, f) - } -} +signed_overflowing_impl! { i8 i16 i32 i64 isize } +unsigned_overflowing_impl! { u8 u16 u32 u64 usize } |
