diff --git a/src/wrapping.rs b/src/wrapping.rs index 2d442ed..cc9dc38 100644 --- a/src/wrapping.rs +++ b/src/wrapping.rs @@ -23,7 +23,6 @@ use crate::{ use core::{ fmt::{Display, Formatter, Result as FmtResult}, iter::{Product, Sum}, - num::Wrapping as CoreWrapping, ops::{ Add, AddAssign, BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Div, DivAssign, Mul, MulAssign, Neg, Not, Rem, RemAssign, Shl, ShlAssign, Shr, ShrAssign, Sub, @@ -255,54 +254,187 @@ impl FromStr for Wrapping { } macro_rules! op { - ( - $Fixed:ident($LeEqU:ident)::$wrapping:ident, - $Op:ident $op:ident, - $OpAssign:ident $op_assign:ident - ) => { - impl $Op>> for Wrapping<$Fixed> { - type Output = Wrapping<$Fixed>; + ($wrapping:ident, $Op:ident $op:ident, $OpAssign:ident $op_assign:ident) => { + impl $Op> for Wrapping { + type Output = Wrapping; #[inline] - fn $op(self, other: Wrapping<$Fixed>) -> Wrapping<$Fixed> { + fn $op(self, other: Wrapping) -> Wrapping { Wrapping((self.0).$wrapping(other.0)) } } - impl<'a, Frac: $LeEqU> $Op>> for &'a Wrapping<$Fixed> { - type Output = Wrapping<$Fixed>; + impl<'a, F: Fixed> $Op> for &'a Wrapping { + type Output = Wrapping; #[inline] - fn $op(self, other: Wrapping<$Fixed>) -> Wrapping<$Fixed> { + fn $op(self, other: Wrapping) -> Wrapping { Wrapping((self.0).$wrapping(other.0)) } } - impl<'a, Frac: $LeEqU> $Op<&'a Wrapping<$Fixed>> for Wrapping<$Fixed> { - type Output = Wrapping<$Fixed>; + impl<'a, F: Fixed> $Op<&'a Wrapping> for Wrapping { + type Output = Wrapping; #[inline] - fn $op(self, other: &Wrapping<$Fixed>) -> Wrapping<$Fixed> { + fn $op(self, other: &Wrapping) -> Wrapping { Wrapping((self.0).$wrapping(other.0)) } } - impl<'a, 'b, Frac: $LeEqU> $Op<&'a Wrapping<$Fixed>> for &'b Wrapping<$Fixed> { - type Output = Wrapping<$Fixed>; + impl<'a, 'b, F: Fixed> $Op<&'a Wrapping> for &'b Wrapping { + type Output = Wrapping; #[inline] - fn $op(self, other: &Wrapping<$Fixed>) -> Wrapping<$Fixed> { + fn $op(self, other: &Wrapping) -> Wrapping { Wrapping((self.0).$wrapping(other.0)) } } - impl $OpAssign>> for Wrapping<$Fixed> { + impl $OpAssign> for Wrapping { #[inline] - fn $op_assign(&mut self, other: Wrapping<$Fixed>) { + fn $op_assign(&mut self, other: Wrapping) { self.0 = (self.0).$wrapping(other.0); } } - impl<'a, Frac: $LeEqU> $OpAssign<&'a Wrapping<$Fixed>> for Wrapping<$Fixed> { + impl<'a, F: Fixed> $OpAssign<&'a Wrapping> for Wrapping { #[inline] - fn $op_assign(&mut self, other: &Wrapping<$Fixed>) { + fn $op_assign(&mut self, other: &Wrapping) { self.0 = (self.0).$wrapping(other.0); } } }; } +macro_rules! op_sh { + ( + $wrapping:ident, $Op:ident $op:ident, $OpAssign:ident $op_assign:ident; + $Rhs:ident $($as_u32:tt)* + ) => { + impl $Op<$Rhs> for Wrapping { + type Output = Wrapping; + #[inline] + fn $op(self, other: $Rhs) -> Wrapping { + Wrapping((self.0).$wrapping(other $($as_u32)*)) + } + } + impl<'a, F: Fixed> $Op<$Rhs> for &'a Wrapping { + type Output = Wrapping; + #[inline] + fn $op(self, other: $Rhs) -> Wrapping { + Wrapping((self.0).$wrapping(other $($as_u32)*)) + } + } + impl<'a, F: Fixed> $Op<&'a $Rhs> for Wrapping { + type Output = Wrapping; + #[inline] + fn $op(self, other: &$Rhs) -> Wrapping { + Wrapping((self.0).$wrapping(*other $($as_u32)*)) + } + } + impl<'a, 'b, F: Fixed> $Op<&'a $Rhs> for &'b Wrapping { + type Output = Wrapping; + #[inline] + fn $op(self, other: &$Rhs) -> Wrapping { + Wrapping((self.0).$wrapping(*other $($as_u32)*)) + } + } + impl $OpAssign<$Rhs> for Wrapping { + #[inline] + fn $op_assign(&mut self, other: $Rhs) { + self.0 = (self.0).$wrapping(other $($as_u32)*); + } + } + impl<'a, F: Fixed> $OpAssign<&'a $Rhs> for Wrapping { + #[inline] + fn $op_assign(&mut self, other: &$Rhs) { + self.0 = (self.0).$wrapping(*other $($as_u32)*); + } + } + }; +} + +impl Neg for Wrapping { + type Output = Wrapping; + #[inline] + fn neg(self) -> Wrapping { + Wrapping((self.0).wrapping_neg()) + } +} + +impl<'a, F: Fixed> Neg for &'a Wrapping { + type Output = Wrapping; + #[inline] + fn neg(self) -> Wrapping { + Wrapping((self.0).wrapping_neg()) + } +} +op! { wrapping_add, Add add, AddAssign add_assign } +op! { wrapping_sub, Sub sub, SubAssign sub_assign } +op! { wrapping_mul, Mul mul, MulAssign mul_assign } +op! { wrapping_div, Div div, DivAssign div_assign } + +impl Not for Wrapping { + type Output = Wrapping; + #[inline] + fn not(self) -> Wrapping { + Wrapping((self.0).not()) + } +} +impl<'a, F: Fixed> Not for &'a Wrapping { + type Output = Wrapping; + #[inline] + fn not(self) -> Wrapping { + Wrapping((self.0).not()) + } +} +op! { bitand, BitAnd bitand, BitAndAssign bitand_assign } +op! { bitor, BitOr bitor, BitOrAssign bitor_assign } +op! { bitxor, BitXor bitxor, BitXorAssign bitxor_assign } + +op_sh! { wrapping_shl, Shl shl, ShlAssign shl_assign; usize as u32 } +op_sh! { wrapping_shr, Shr shr, ShrAssign shr_assign; usize as u32 } +op_sh! { wrapping_shl, Shl shl, ShlAssign shl_assign; u32 } +op_sh! { wrapping_shr, Shr shr, ShrAssign shr_assign; u32 } + +impl Sum> for Wrapping { + fn sum(iter: I) -> Wrapping + where + I: Iterator>, + { + iter.fold(Wrapping(F::from_num(0)), Add::add) + } +} + +impl<'a, F: 'a + Fixed> Sum<&'a Wrapping> for Wrapping { + fn sum(iter: I) -> Wrapping + where + I: Iterator>, + { + iter.fold(Wrapping(F::from_num(0)), Add::add) + } +} + +impl Product> for Wrapping { + fn product(mut iter: I) -> Wrapping + where + I: Iterator>, + { + match iter.next() { + None => Wrapping(1.wrapping_to_fixed()), + Some(first) => iter.fold(first, Mul::mul), + } + } +} + +impl<'a, F: 'a + Fixed> Product<&'a Wrapping> for Wrapping { + fn product(mut iter: I) -> Wrapping + where + I: Iterator>, + { + match iter.next() { + None => Wrapping(1.wrapping_to_fixed()), + Some(first) => iter.fold(*first, Mul::mul), + } + } +} + +// The following cannot be implemented for Wrapping where F: Fixed, +// otherwise there will be a conflicting implementation error, so we +// need to implement on typed direcly. + macro_rules! op_bits { ( $Fixed:ident($LeEqU:ident)::$wrapping:ident, @@ -353,125 +485,13 @@ macro_rules! op_bits { }; } -macro_rules! op_sh { - ( - $Fixed:ident($LeEqU:ident), - $Op:ident $op:ident, - $OpAssign:ident $op_assign:ident - ) => { - impl $Op for Wrapping<$Fixed> { - type Output = Wrapping<$Fixed>; - #[inline] - fn $op(self, other: usize) -> Wrapping<$Fixed> { - Wrapping($Fixed::from_bits( - CoreWrapping((self.0).to_bits()).$op(other).0, - )) - } - } - impl $OpAssign for Wrapping<$Fixed> { - #[inline] - fn $op_assign(&mut self, other: usize) { - self.0 = (self.0).$op(other); - } - } - impl<'a, Frac: $LeEqU> $OpAssign<&'a usize> for Wrapping<$Fixed> { - #[inline] - fn $op_assign(&mut self, other: &usize) { - self.0 = (self.0).$op(*other); - } - } - }; -} - macro_rules! ops { ($Fixed:ident($LeEqU:ident, $Bits:ident)) => { - impl Neg for Wrapping<$Fixed> { - type Output = Wrapping<$Fixed>; - #[inline] - fn neg(self) -> Wrapping<$Fixed> { - Wrapping((self.0).wrapping_neg()) - } - } - impl<'a, Frac: $LeEqU> Neg for &'a Wrapping<$Fixed> { - type Output = Wrapping<$Fixed>; - #[inline] - fn neg(self) -> Wrapping<$Fixed> { - Wrapping((self.0).wrapping_neg()) - } - } - op! { $Fixed($LeEqU)::wrapping_add, Add add, AddAssign add_assign } - op! { $Fixed($LeEqU)::wrapping_sub, Sub sub, SubAssign sub_assign } - op! { $Fixed($LeEqU)::wrapping_mul, Mul mul, MulAssign mul_assign } - op! { $Fixed($LeEqU)::wrapping_div, Div div, DivAssign div_assign } op_bits! { $Fixed($LeEqU)::wrapping_mul_int, $Bits, Mul mul, MulAssign mul_assign } op_bits! { $Fixed($LeEqU)::wrapping_div_int, $Bits, Div div, DivAssign div_assign } op_bits! { $Fixed($LeEqU)::wrapping_rem_int, $Bits, Rem rem, RemAssign rem_assign } - - impl Not for Wrapping<$Fixed> { - type Output = Wrapping<$Fixed>; - #[inline] - fn not(self) -> Wrapping<$Fixed> { - Wrapping((self.0).not()) - } - } - impl<'a, Frac: $LeEqU> Not for &'a Wrapping<$Fixed> { - type Output = Wrapping<$Fixed>; - #[inline] - fn not(self) -> Wrapping<$Fixed> { - Wrapping((self.0).not()) - } - } - op! { $Fixed($LeEqU)::bitand, BitAnd bitand, BitAndAssign bitand_assign } - op! { $Fixed($LeEqU)::bitor, BitOr bitor, BitOrAssign bitor_assign } - op! { $Fixed($LeEqU)::bitxor, BitXor bitxor, BitXorAssign bitxor_assign } - - op_sh! { $Fixed($LeEqU), Shl shl, ShlAssign shl_assign } - op_sh! { $Fixed($LeEqU), Shr shr, ShrAssign shr_assign } - - impl Sum>> for Wrapping<$Fixed> { - fn sum(iter: I) -> Wrapping<$Fixed> - where - I: Iterator>>, - { - iter.fold(Wrapping($Fixed::from_bits(0)), Add::add) - } - } - - impl<'a, Frac: 'a + $LeEqU> Sum<&'a Wrapping<$Fixed>> for Wrapping<$Fixed> { - fn sum(iter: I) -> Wrapping<$Fixed> - where - I: Iterator>>, - { - iter.fold(Wrapping($Fixed::from_bits(0)), Add::add) - } - } - - impl Product>> for Wrapping<$Fixed> { - fn product(mut iter: I) -> Wrapping<$Fixed> - where - I: Iterator>>, - { - match iter.next() { - None => Wrapping(1.wrapping_to_fixed()), - Some(first) => iter.fold(first, Mul::mul), - } - } - } - - impl<'a, Frac: 'a + $LeEqU> Product<&'a Wrapping<$Fixed>> for Wrapping<$Fixed> { - fn product(mut iter: I) -> Wrapping<$Fixed> - where - I: Iterator>>, - { - match iter.next() { - None => Wrapping(1.wrapping_to_fixed()), - Some(first) => iter.fold(*first, Mul::mul), - } - } - } }; } - ops! { FixedI8(LeEqU8, i8) } ops! { FixedI16(LeEqU16, i16) } ops! { FixedI32(LeEqU32, i32) }