gst/Signed: impl option-operations traits

This commit is contained in:
François Laignel 2022-09-19 19:34:11 +02:00 committed by François Laignel
parent 183a399d1d
commit 8595b67218
2 changed files with 140 additions and 0 deletions

View file

@ -541,6 +541,17 @@ mod tests {
Err(opt_ops::Error::Overflow) Err(opt_ops::Error::Overflow)
); );
assert_eq!(P_CT_1.opt_checked_add(P_CT_1), Ok(Some(P_CT_2)));
assert_eq!(P_CT_1.opt_checked_add(Some(N_CT_2)), Ok(Some(N_CT_1)));
assert_eq!(Some(P_CT_1).opt_checked_add(Some(P_CT_1)), Ok(Some(P_CT_2)));
assert_eq!(P_CT_1.opt_checked_add(None), Ok(None));
assert_eq!(Some(N_CT_1).opt_checked_add(None), Ok(None));
assert_eq!(
ClockTime::MAX.into_positive().opt_checked_add(Some(P_CT_1)),
Err(opt_ops::Error::Overflow)
);
assert_eq!(CT_2.checked_sub(CT_1), Some(CT_1)); assert_eq!(CT_2.checked_sub(CT_1), Some(CT_1));
assert_eq!(P_CT_3.checked_sub(P_CT_2), Some(P_CT_1)); assert_eq!(P_CT_3.checked_sub(P_CT_2), Some(P_CT_1));
assert_eq!(P_CT_2.checked_sub(P_CT_3), Some(N_CT_1)); assert_eq!(P_CT_2.checked_sub(P_CT_3), Some(N_CT_1));
@ -562,12 +573,18 @@ mod tests {
Err(opt_ops::Error::Overflow) Err(opt_ops::Error::Overflow)
); );
assert_eq!(P_CT_2.opt_checked_sub(Some(N_CT_1)), Ok(Some(P_CT_3)));
assert_eq!(Some(N_CT_2).opt_checked_sub(P_CT_1), Ok(Some(N_CT_3)));
assert_eq!(CT_1.checked_mul(2), Some(CT_2)); assert_eq!(CT_1.checked_mul(2), Some(CT_2));
assert_eq!(P_CT_1.checked_mul(2), Some(P_CT_2)); assert_eq!(P_CT_1.checked_mul(2), Some(P_CT_2));
assert_eq!(P_CT_1.checked_mul(-2), Some(N_CT_2)); assert_eq!(P_CT_1.checked_mul(-2), Some(N_CT_2));
assert_eq!(N_CT_1.checked_mul(2), Some(N_CT_2)); assert_eq!(N_CT_1.checked_mul(2), Some(N_CT_2));
assert_eq!(N_CT_1.checked_mul(-2), Some(P_CT_2)); assert_eq!(N_CT_1.checked_mul(-2), Some(P_CT_2));
assert_eq!(Some(P_CT_1).opt_checked_mul(-2i64), Ok(Some(N_CT_2)));
assert_eq!(N_CT_1.opt_checked_mul(2u64), Ok(Some(N_CT_2)));
assert_eq!(P_CT_1.checked_mul_unsigned(2u64), Some(P_CT_2)); assert_eq!(P_CT_1.checked_mul_unsigned(2u64), Some(P_CT_2));
assert_eq!(N_CT_1.checked_mul_unsigned(2u64), Some(N_CT_2)); assert_eq!(N_CT_1.checked_mul_unsigned(2u64), Some(N_CT_2));
@ -577,6 +594,9 @@ mod tests {
assert_eq!(N_CT_3.checked_div(3), Some(N_CT_1)); assert_eq!(N_CT_3.checked_div(3), Some(N_CT_1));
assert_eq!(N_CT_3.checked_div(-3), Some(P_CT_1)); assert_eq!(N_CT_3.checked_div(-3), Some(P_CT_1));
assert_eq!(Some(P_CT_3).opt_checked_div(-3i64), Ok(Some(N_CT_1)));
assert_eq!(N_CT_3.opt_checked_div(3u64), Ok(Some(N_CT_1)));
assert_eq!(P_CT_3.checked_div_unsigned(3u64), Some(P_CT_1)); assert_eq!(P_CT_3.checked_div_unsigned(3u64), Some(P_CT_1));
assert_eq!(N_CT_3.checked_div_unsigned(3u64), Some(N_CT_1)); assert_eq!(N_CT_3.checked_div_unsigned(3u64), Some(N_CT_1));
} }

View file

@ -630,6 +630,46 @@ macro_rules! impl_signed_ops(
} }
} }
} }
impl OptionOperations for crate::Signed<$type> {}
impl OptionCheckedAdd for crate::Signed<$type> {
type Output = Self;
fn opt_checked_add(
self,
rhs: Self,
) -> Result<Option<Self::Output>, opt_ops::Error> {
self.checked_add(rhs)
.ok_or(opt_ops::Error::Overflow)
.map(Some)
}
}
impl OptionSaturatingAdd for crate::Signed<$type> {
type Output = Self;
fn opt_saturating_add(self, rhs: Self) -> Option<Self::Output> {
Some(self.saturating_add(rhs))
}
}
impl OptionCheckedSub for crate::Signed<$type> {
type Output = Self;
fn opt_checked_sub(
self,
rhs: Self,
) -> Result<Option<Self::Output>, opt_ops::Error> {
self.checked_sub(rhs)
.ok_or(opt_ops::Error::Overflow)
.map(Some)
}
}
impl OptionSaturatingSub for crate::Signed<$type> {
type Output = Self;
fn opt_saturating_sub(self, rhs: Self) -> Option<Self::Output> {
Some(self.saturating_sub(rhs))
}
}
}; };
); );
@ -873,6 +913,86 @@ macro_rules! impl_signed_div_mul(
*self = std::ops::Mul::mul(*self, rhs); *self = std::ops::Mul::mul(*self, rhs);
} }
} }
impl OptionCheckedDiv<$signed_rhs> for crate::Signed<$type> {
type Output = Self;
fn opt_checked_div(self, rhs: $signed_rhs) -> Result<Option<Self::Output>, opt_ops::Error> {
if rhs == 0 {
return Err(opt_ops::Error::DivisionByZero);
}
self.checked_div(rhs)
.ok_or(opt_ops::Error::Overflow)
.map(Some)
}
}
impl OptionCheckedMul<$signed_rhs> for crate::Signed<$type> {
type Output = Self;
fn opt_checked_mul(self, rhs: $signed_rhs) -> Result<Option<Self::Output>, opt_ops::Error> {
self.checked_mul(rhs)
.ok_or(opt_ops::Error::Overflow)
.map(Some)
}
}
impl OptionSaturatingMul<$signed_rhs> for crate::Signed<$type> {
type Output = Self;
fn opt_saturating_mul(self, rhs: $signed_rhs) -> Option<Self::Output> {
Some(self.saturating_mul(rhs))
}
}
impl OptionCheckedRem<$signed_rhs> for crate::Signed<$type> {
type Output = Self;
fn opt_checked_rem(self, rhs: $signed_rhs) -> Result<Option<Self::Output>, opt_ops::Error> {
if rhs == 0 {
return Err(opt_ops::Error::DivisionByZero);
}
self.checked_rem(rhs)
.ok_or(opt_ops::Error::Overflow)
.map(Some)
}
}
impl OptionCheckedDiv<$inner_type> for crate::Signed<$type> {
type Output = Self;
fn opt_checked_div(self, rhs: $inner_type) -> Result<Option<Self::Output>, opt_ops::Error> {
if rhs == 0 {
return Err(opt_ops::Error::DivisionByZero);
}
self.checked_div_unsigned(rhs)
.ok_or(opt_ops::Error::Overflow)
.map(Some)
}
}
impl OptionCheckedMul<$inner_type> for crate::Signed<$type> {
type Output = Self;
fn opt_checked_mul(self, rhs: $inner_type) -> Result<Option<Self::Output>, opt_ops::Error> {
self.checked_mul_unsigned(rhs)
.ok_or(opt_ops::Error::Overflow)
.map(Some)
}
}
impl OptionSaturatingMul<$inner_type> for crate::Signed<$type> {
type Output = Self;
fn opt_saturating_mul(self, rhs: $inner_type) -> Option<Self::Output> {
Some(self.saturating_mul_unsigned(rhs))
}
}
impl OptionCheckedRem<$inner_type> for crate::Signed<$type> {
type Output = Self;
fn opt_checked_rem(self, rhs: $inner_type) -> Result<Option<Self::Output>, opt_ops::Error> {
if rhs == 0 {
return Err(opt_ops::Error::DivisionByZero);
}
self.checked_rem_unsigned(rhs)
.ok_or(opt_ops::Error::Overflow)
.map(Some)
}
}
}; };
); );