diff --git a/lib/common/src/integer.rs b/lib/common/src/integer.rs index 670102f..6d4d69f 100644 --- a/lib/common/src/integer.rs +++ b/lib/common/src/integer.rs @@ -2,19 +2,25 @@ pub use fixed_wide::fixed::{Fixed,Fix}; pub use ratio_ops::ratio::{Ratio,Divide}; //integer units + +/// specific example of a "default" time type #[derive(Clone,Copy,Hash,Eq,PartialEq,PartialOrd,Debug)] -pub struct Time(i64); -impl Time{ - pub const MIN:Self=Self(i64::MIN); - pub const MAX:Self=Self(i64::MAX); - pub const ZERO:Self=Self(0); - pub const ONE_SECOND:Self=Self(1_000_000_000); - pub const ONE_MILLISECOND:Self=Self(1_000_000); - pub const ONE_MICROSECOND:Self=Self(1_000); - pub const ONE_NANOSECOND:Self=Self(1); +pub enum TimeInner{} +pub type RawTime=Time<TimeInner>; + +#[derive(Clone,Copy,Hash,Eq,PartialEq,PartialOrd,Debug)] +pub struct Time<T>(i64,core::marker::PhantomData<T>); +impl<T> Time<T>{ + pub const MIN:Self=Self::raw(i64::MIN); + pub const MAX:Self=Self::raw(i64::MAX); + pub const ZERO:Self=Self::raw(0); + pub const ONE_SECOND:Self=Self::raw(1_000_000_000); + pub const ONE_MILLISECOND:Self=Self::raw(1_000_000); + pub const ONE_MICROSECOND:Self=Self::raw(1_000); + pub const ONE_NANOSECOND:Self=Self::raw(1); #[inline] pub const fn raw(num:i64)->Self{ - Self(num) + Self(num,core::marker::PhantomData) } #[inline] pub const fn get(self)->i64{ @@ -22,19 +28,19 @@ impl Time{ } #[inline] pub const fn from_secs(num:i64)->Self{ - Self(Self::ONE_SECOND.0*num) + Self::raw(Self::ONE_SECOND.0*num) } #[inline] pub const fn from_millis(num:i64)->Self{ - Self(Self::ONE_MILLISECOND.0*num) + Self::raw(Self::ONE_MILLISECOND.0*num) } #[inline] pub const fn from_micros(num:i64)->Self{ - Self(Self::ONE_MICROSECOND.0*num) + Self::raw(Self::ONE_MICROSECOND.0*num) } #[inline] pub const fn from_nanos(num:i64)->Self{ - Self(Self::ONE_NANOSECOND.0*num) + Self::raw(Self::ONE_NANOSECOND.0*num) } //should I have checked subtraction? force all time variables to be positive? #[inline] @@ -45,14 +51,18 @@ impl Time{ pub const fn to_ratio(self)->Ratio<Planar64,Planar64>{ Ratio::new(Planar64::raw(self.0),Planar64::raw(1_000_000_000)) } -} -impl From<Planar64> for Time{ #[inline] - fn from(value:Planar64)->Self{ - Time((value*Planar64::raw(1_000_000_000)).fix_1().to_raw()) + pub const fn coerce<U>(self)->Time<U>{ + Time::raw(self.0) } } -impl<Num,Den,N1,T1> From<Ratio<Num,Den>> for Time +impl<T> From<Planar64> for Time<T>{ + #[inline] + fn from(value:Planar64)->Self{ + Self::raw((value*Planar64::raw(1_000_000_000)).fix_1().to_raw()) + } +} +impl<T,Num,Den,N1,T1> From<Ratio<Num,Den>> for Time<T> where Num:core::ops::Mul<Planar64,Output=N1>, N1:Divide<Den,Output=T1>, @@ -60,34 +70,34 @@ impl<Num,Den,N1,T1> From<Ratio<Num,Den>> for Time { #[inline] fn from(value:Ratio<Num,Den>)->Self{ - Time((value*Planar64::raw(1_000_000_000)).divide().fix().to_raw()) + Self::raw((value*Planar64::raw(1_000_000_000)).divide().fix().to_raw()) } } -impl std::fmt::Display for Time{ +impl<T> std::fmt::Display for Time<T>{ #[inline] fn fmt(&self,f:&mut std::fmt::Formatter<'_>)->std::fmt::Result{ write!(f,"{}s+{:09}ns",self.0/Self::ONE_SECOND.0,self.0%Self::ONE_SECOND.0) } } -impl std::default::Default for Time{ +impl<T> std::default::Default for Time<T>{ fn default()->Self{ - Self(0) + Self::raw(0) } } -impl std::ops::Neg for Time{ - type Output=Time; +impl<T> std::ops::Neg for Time<T>{ + type Output=Self; #[inline] fn neg(self)->Self::Output { - Time(-self.0) + Self::raw(-self.0) } } macro_rules! impl_time_additive_operator { ($trait:ty, $method:ident) => { - impl $trait for Time{ - type Output=Time; + impl<T> $trait for Time<T>{ + type Output=Self; #[inline] fn $method(self,rhs:Self)->Self::Output { - Time(self.0.$method(rhs.0)) + Self::raw(self.0.$method(rhs.0)) } } }; @@ -97,7 +107,7 @@ impl_time_additive_operator!(core::ops::Sub,sub); impl_time_additive_operator!(core::ops::Rem,rem); macro_rules! impl_time_additive_assign_operator { ($trait:ty, $method:ident) => { - impl $trait for Time{ + impl<T> $trait for Time<T>{ #[inline] fn $method(&mut self,rhs:Self){ self.0.$method(rhs.0) @@ -108,53 +118,60 @@ macro_rules! impl_time_additive_assign_operator { impl_time_additive_assign_operator!(core::ops::AddAssign,add_assign); impl_time_additive_assign_operator!(core::ops::SubAssign,sub_assign); impl_time_additive_assign_operator!(core::ops::RemAssign,rem_assign); -impl std::ops::Mul for Time{ +impl<T> std::ops::Mul for Time<T>{ type Output=Ratio<fixed_wide::fixed::Fixed<2,64>,fixed_wide::fixed::Fixed<2,64>>; #[inline] fn mul(self,rhs:Self)->Self::Output{ Ratio::new(Fixed::raw(self.0)*Fixed::raw(rhs.0),Fixed::raw_digit(1_000_000_000i64.pow(2))) } } -impl std::ops::Div<i64> for Time{ - type Output=Time; +impl<T> std::ops::Div<i64> for Time<T>{ + type Output=Self; #[inline] fn div(self,rhs:i64)->Self::Output{ - Time(self.0/rhs) + Self::raw(self.0/rhs) } } -impl std::ops::Mul<i64> for Time{ - type Output=Time; +impl<T> std::ops::Mul<i64> for Time<T>{ + type Output=Self; #[inline] fn mul(self,rhs:i64)->Self::Output{ - Time(self.0*rhs) + Self::raw(self.0*rhs) } } -impl core::ops::Mul<Time> for Planar64{ +impl<T> core::ops::Mul<Time<T>> for Planar64{ type Output=Ratio<Fixed<2,64>,Planar64>; - fn mul(self,rhs:Time)->Self::Output{ + fn mul(self,rhs:Time<T>)->Self::Output{ Ratio::new(self*Fixed::raw(rhs.0),Planar64::raw(1_000_000_000)) } } -#[test] -fn time_from_planar64(){ - let a:Time=Planar64::from(1).into(); - assert_eq!(a,Time::ONE_SECOND); -} -#[test] -fn time_from_ratio(){ - let a:Time=Ratio::new(Planar64::from(1),Planar64::from(1)).into(); - assert_eq!(a,Time::ONE_SECOND); -} -#[test] -fn time_squared(){ - let a=Time::from_secs(2); - assert_eq!(a*a,Ratio::new(Fixed::<2,64>::raw_digit(1_000_000_000i64.pow(2))*4,Fixed::<2,64>::raw_digit(1_000_000_000i64.pow(2)))); -} -#[test] -fn time_times_planar64(){ - let a=Time::from_secs(2); - let b=Planar64::from(2); - assert_eq!(b*a,Ratio::new(Fixed::<2,64>::raw_digit(1_000_000_000*(1<<32))<<2,Fixed::<1,32>::raw_digit(1_000_000_000))); +#[cfg(test)] +mod test_time{ + use super::*; + #[derive(Clone,Copy,Hash,Eq,PartialEq,PartialOrd,Debug)] + struct Test; + type Time=super::Time<Test>; + #[test] + fn time_from_planar64(){ + let a:Time=Planar64::from(1).into(); + assert_eq!(a,Time::ONE_SECOND); + } + #[test] + fn time_from_ratio(){ + let a:Time=Ratio::new(Planar64::from(1),Planar64::from(1)).into(); + assert_eq!(a,Time::ONE_SECOND); + } + #[test] + fn time_squared(){ + let a=Time::from_secs(2); + assert_eq!(a*a,Ratio::new(Fixed::<2,64>::raw_digit(1_000_000_000i64.pow(2))*4,Fixed::<2,64>::raw_digit(1_000_000_000i64.pow(2)))); + } + #[test] + fn time_times_planar64(){ + let a=Time::from_secs(2); + let b=Planar64::from(2); + assert_eq!(b*a,Ratio::new(Fixed::<2,64>::raw_digit(1_000_000_000*(1<<32))<<2,Fixed::<1,32>::raw_digit(1_000_000_000))); + } } #[inline]