diff --git a/lib/ratio_ops/src/ratio.rs b/lib/ratio_ops/src/ratio.rs index 18e582d..a61a6cc 100644 --- a/lib/ratio_ops/src/ratio.rs +++ b/lib/ratio_ops/src/ratio.rs @@ -68,54 +68,57 @@ impl_ratio_method!(Add,add,add_ratio); impl_ratio_method!(Sub,sub,sub_ratio); impl_ratio_method!(Rem,rem,rem_ratio); -/// Comparing two ratios needs to know the parity of the denominators -/// For signed integers this can be implemented with is_negative() -pub trait Parity{ - fn parity(&self)->bool; +/// The denominator cannot be negative +/// otherwise cross-multiplying changes the comparison +pub trait ToUnsigned{ + type Unsigned; + fn to_unsigned(self)->(bool,Self::Unsigned); } -macro_rules! impl_parity_unsigned{ +macro_rules! impl_to_unsigned_unsigned{ ($($type:ty),*)=>{ $( - impl Parity for $type{ - fn parity(&self)->bool{ - false + impl ToUnsigned for $type{ + type Unsigned=Self; + fn to_unsigned(self)->(bool,Self::Unsigned){ + (false,self) } } )* }; } -macro_rules! impl_parity_signed{ - ($($type:ty),*)=>{ +macro_rules! impl_to_unsigned_signed{ + ($(($type:ty,$unsigned:ty)),*)=>{ $( - impl Parity for $type{ - fn parity(&self)->bool{ - self.is_negative() + impl ToUnsigned for $type{ + type Unsigned=$unsigned; + fn to_unsigned(self)->(bool,Self::Unsigned){ + (self.is_negative(),self.unsigned_abs()) } } )* }; } -macro_rules! impl_parity_float{ +macro_rules! impl_to_unsigned_float{ ($($type:ty),*)=>{ $( - impl Parity for $type{ - fn parity(&self)->bool{ - self.is_sign_negative() + impl ToUnsigned for $type{ + type Unsigned=Self; + fn to_unsigned(self)->(bool,Self::Unsigned){ + (self.is_sign_negative(),-self) } } )* }; } - -impl_parity_unsigned!(u8,u16,u32,u64,u128,usize); -impl_parity_signed!(i8,i16,i32,i64,i128,isize); -impl_parity_float!(f32,f64); +impl_to_unsigned_unsigned!(u8,u16,u32,u64,u128,usize); +impl_to_unsigned_signed!((i8,u8),(i16,u16),(i32,u32),(i64,u64),(i128,u128),(isize,usize)); +impl_to_unsigned_float!(f32,f64); macro_rules! impl_ratio_ord_method{ ($method:ident, $ratio_method:ident, $output:ty)=>{ - impl<LhsNum,LhsDen:Parity> Ratio<LhsNum,LhsDen>{ + impl<LhsNum,LhsDen:ToUnsigned> Ratio<LhsNum,LhsDen>{ #[inline] - pub fn $ratio_method<RhsNum,RhsDen:Parity,T>(self,rhs:Ratio<RhsNum,RhsDen>)->$output + pub fn $ratio_method<RhsNum,RhsDen:ToUnsigned,T>(self,rhs:Ratio<RhsNum,RhsDen>)->$output where LhsNum:core::ops::Mul<RhsDen,Output=T>, LhsDen:core::ops::Mul<RhsNum,Output=T>, @@ -273,9 +276,9 @@ impl<Num,Den> Eq for Ratio<Num,Den> where Self:PartialEq{} impl<LhsNum,LhsDen,RhsNum,RhsDen,T,U> PartialOrd<Ratio<RhsNum,RhsDen>> for Ratio<LhsNum,LhsDen> where LhsNum:Copy, - LhsDen:Copy+Parity, + LhsDen:Copy+ToUnsigned, RhsNum:Copy, - RhsDen:Copy+Parity, + RhsDen:Copy+ToUnsigned, LhsNum:core::ops::Mul<RhsDen,Output=T>, LhsDen:core::ops::Mul<RhsNum,Output=T>, RhsNum:core::ops::Mul<LhsDen,Output=U>, @@ -290,7 +293,7 @@ impl<LhsNum,LhsDen,RhsNum,RhsDen,T,U> PartialOrd<Ratio<RhsNum,RhsDen>> for Ratio impl<Num,Den,T> Ord for Ratio<Num,Den> where Num:Copy, - Den:Copy+Parity, + Den:Copy+ToUnsigned, Num:core::ops::Mul<Den,Output=T>, Den:core::ops::Mul<Num,Output=T>, T:Ord,