diff --git a/agb-fixnum/src/lib.rs b/agb-fixnum/src/lib.rs index 56fd3979..6b75318f 100644 --- a/agb-fixnum/src/lib.rs +++ b/agb-fixnum/src/lib.rs @@ -11,6 +11,7 @@ use core::{ Sub, SubAssign, }, }; +use num_traits::Signed; #[doc(hidden)] /// Used internally by the [num!] macro which should be used instead. @@ -32,49 +33,25 @@ macro_rules! num { /// A trait for everything required to use as the internal representation of the /// fixed point number. -pub trait Number: - Sized - + Copy - + PartialOrd - + Ord - + PartialEq - + Eq - + Add - + Sub - + Rem - + Div - + Mul -{ -} +pub trait Number: Copy + PartialOrd + Ord + num_traits::Num {} impl Number for Num {} impl Number for I {} /// A trait for integers that don't implement unary negation pub trait FixedWidthUnsignedInteger: - Sized - + Copy + Copy + PartialOrd + Ord - + PartialEq - + Eq + Shl + Shr - + Add - + Sub - + Not + BitAnd - + Rem - + Div - + Mul + From + Debug + Display + + num_traits::Num + + Not { - /// Returns the representation of zero - fn zero() -> Self; - /// Returns the representation of one - fn one() -> Self; /// Returns the representation of ten fn ten() -> Self; /// Converts an i32 to it's own representation, panics on failure @@ -84,23 +61,13 @@ pub trait FixedWidthUnsignedInteger: } /// Trait for an integer that includes negation -pub trait FixedWidthSignedInteger: FixedWidthUnsignedInteger + Neg { - #[must_use] - /// Returns the absolute value of the number - fn fixed_abs(self) -> Self; -} +pub trait FixedWidthSignedInteger: FixedWidthUnsignedInteger + num_traits::sign::Signed {} + +impl FixedWidthSignedInteger for I {} macro_rules! fixed_width_unsigned_integer_impl { ($T: ty, $Upcast: ident) => { impl FixedWidthUnsignedInteger for $T { - #[inline(always)] - fn zero() -> Self { - 0 - } - #[inline(always)] - fn one() -> Self { - 1 - } #[inline(always)] fn ten() -> Self { 10 @@ -119,6 +86,8 @@ macro_rules! upcast_multiply_impl { ($T: ty, optimised_64_bit) => { #[inline(always)] fn upcast_multiply(a: Self, b: Self, n: usize) -> Self { + use num_traits::One; + let mask = (Self::one() << n).wrapping_sub(1); let a_floor = a >> n; @@ -144,17 +113,6 @@ macro_rules! upcast_multiply_impl { }; } -macro_rules! fixed_width_signed_integer_impl { - ($T: ty) => { - impl FixedWidthSignedInteger for $T { - #[inline(always)] - fn fixed_abs(self) -> Self { - self.abs() - } - } - }; -} - fixed_width_unsigned_integer_impl!(u8, u32); fixed_width_unsigned_integer_impl!(i16, i32); fixed_width_unsigned_integer_impl!(u16, u32); @@ -162,9 +120,6 @@ fixed_width_unsigned_integer_impl!(u16, u32); fixed_width_unsigned_integer_impl!(i32, optimised_64_bit); fixed_width_unsigned_integer_impl!(u32, optimised_64_bit); -fixed_width_signed_integer_impl!(i16); -fixed_width_signed_integer_impl!(i32); - /// A fixed point number represented using `I` with `N` bits of fractional precision #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] #[repr(transparent)] @@ -546,7 +501,7 @@ impl Num { /// assert_eq!(n.abs(), num!(5.5)); /// ``` pub fn abs(self) -> Self { - Num(self.0.fixed_abs()) + Num(self.0.abs()) } /// Calculates the cosine of a fixed point number with the domain of [0, 1]. @@ -595,6 +550,28 @@ impl Num { } } +impl num_traits::sign::Signed for Num { + fn abs(&self) -> Self { + Self::abs(*self) + } + + fn abs_sub(&self, other: &Self) -> Self { + Self(self.0.abs_sub(&other.0)) + } + + fn signum(&self) -> Self { + Self(self.0.signum()) + } + + fn is_positive(&self) -> bool { + self.0.is_positive() + } + + fn is_negative(&self) -> bool { + self.0.is_negative() + } +} + impl Display for Num { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { let mut integral = self.0 >> N; @@ -759,12 +736,12 @@ impl SubAssign for Vector2D { } } -impl Vector2D { +impl Vector2D { /// Calculates the absolute value of the x and y components. pub fn abs(self) -> Self { Self { - x: self.x.fixed_abs(), - y: self.y.fixed_abs(), + x: self.x.abs(), + y: self.y.abs(), } } } @@ -1083,13 +1060,13 @@ impl Rect { } } -impl Rect { +impl Rect { /// Makes a rectangle that represents the equivalent location in space but with a positive size pub fn abs(self) -> Self { Self { position: ( - self.position.x + self.size.x.min(0.into()), - self.position.y + self.size.y.min(0.into()), + self.position.x + self.size.x.min(T::zero()), + self.position.y + self.size.y.min(T::zero()), ) .into(), size: self.size.abs(),