mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer-rs.git
synced 2024-12-25 09:30:30 +00:00
gst/format: fix some ops and add others
Some operations were implemented on types that wouldn't result in the expected physical unit. E.g.: - `ClockTime / ClockTime` results in a unit-less factor. - `u64 / ClockTime` would result in a `1 / ClockTime`. Since we don't use any `Frequency` type, this operation is removed. Users should use the `ClockTime` accessors to compute the expected value. This commit also adds: - multiplications with integers as the left hand side operands. - `Partial{Eq,Ord} for `Signed<T>` with `T` as left hand side operand. - `opt_add` / `opt_sub` for `Signed<T>` with `T` as left or right hand side operands. - missing tests for `Partial{Eq,Ord}` and `OptionOrd`. This implementation can interfere with unrelated code and was removed: - `Signed<usize>.` `PartialOrd` makes existing code computing the len of slices needing type annotation because the len is later used in a comparison for which the compiler is unable to determine if the len is `Signed<usize>` or `usize`.
This commit is contained in:
parent
eb4d997f0a
commit
57d8d46ab6
4 changed files with 443 additions and 43 deletions
|
@ -288,7 +288,7 @@ impl TryFrom<Duration> for ClockTime {
|
|||
|
||||
let nanos = d.as_nanos();
|
||||
|
||||
// Note: `std::u64::MAX` is `ClockTime::None`.
|
||||
// Note: `std::u64::MAX` is `ClockTime::NONE`.
|
||||
if nanos >= std::u64::MAX as u128 {
|
||||
return Err(DurationError);
|
||||
}
|
||||
|
@ -527,6 +527,8 @@ mod tests {
|
|||
const CT_20: ClockTime = ClockTime::from_nseconds(20);
|
||||
const CT_30: ClockTime = ClockTime::from_nseconds(30);
|
||||
|
||||
const P_CT_0: Signed<ClockTime> = Signed::Positive(ClockTime::ZERO);
|
||||
const P_CT_NONE: Option<Signed<ClockTime>> = None;
|
||||
const P_CT_1: Signed<ClockTime> = Signed::Positive(ClockTime::from_nseconds(1));
|
||||
const P_CT_2: Signed<ClockTime> = Signed::Positive(ClockTime::from_nseconds(2));
|
||||
const P_CT_3: Signed<ClockTime> = Signed::Positive(ClockTime::from_nseconds(3));
|
||||
|
@ -558,6 +560,8 @@ mod tests {
|
|||
assert_eq!(CT_30 - CT_30, ClockTime::ZERO);
|
||||
assert_eq!(CT_10 * 3, CT_30);
|
||||
assert_eq!(3 * CT_10, CT_30);
|
||||
assert_eq!(CT_20 / 2, CT_10);
|
||||
assert_eq!(CT_20 / CT_2, 10);
|
||||
assert_eq!(CT_30.nseconds(), 30);
|
||||
|
||||
assert_eq!(P_CT_1 + P_CT_2, P_CT_3);
|
||||
|
@ -567,17 +571,30 @@ mod tests {
|
|||
assert_eq!(N_CT_2 + P_CT_3, P_CT_1);
|
||||
assert_eq!(N_CT_2 + N_CT_1, N_CT_3);
|
||||
|
||||
assert_eq!(CT_1 + P_CT_2, P_CT_3);
|
||||
assert_eq!(P_CT_1 + CT_2, P_CT_3);
|
||||
assert_eq!(CT_3 + N_CT_1, P_CT_2);
|
||||
assert_eq!(N_CT_1 + CT_2, P_CT_1);
|
||||
|
||||
assert_eq!(P_CT_3 - P_CT_2, P_CT_1);
|
||||
assert_eq!(P_CT_2 - P_CT_3, N_CT_1);
|
||||
assert_eq!(P_CT_2 - N_CT_1, P_CT_3);
|
||||
assert_eq!(N_CT_2 - P_CT_1, N_CT_3);
|
||||
assert_eq!(N_CT_3 - N_CT_1, N_CT_2);
|
||||
|
||||
assert_eq!(CT_3 - P_CT_2, P_CT_1);
|
||||
assert_eq!(P_CT_3 - CT_2, P_CT_1);
|
||||
assert_eq!(N_CT_2 - CT_1, N_CT_3);
|
||||
assert_eq!(CT_2 - N_CT_1, P_CT_3);
|
||||
|
||||
assert_eq!(P_CT_1 * 2i64, P_CT_2);
|
||||
assert_eq!(P_CT_1 * -2i64, N_CT_2);
|
||||
assert_eq!(N_CT_1 * 2i64, N_CT_2);
|
||||
assert_eq!(N_CT_1 * -2i64, P_CT_2);
|
||||
|
||||
assert_eq!(2i64 * P_CT_1, P_CT_2);
|
||||
assert_eq!(-2i64 * P_CT_1, N_CT_2);
|
||||
|
||||
assert_eq!(P_CT_1 * 2u64, P_CT_2);
|
||||
assert_eq!(N_CT_1 * 2u64, N_CT_2);
|
||||
|
||||
|
@ -586,6 +603,8 @@ mod tests {
|
|||
assert_eq!(N_CT_2 / 2i64, N_CT_1);
|
||||
assert_eq!(N_CT_2 / -2i64, P_CT_1);
|
||||
|
||||
assert_eq!(P_CT_2 / N_CT_2, Signed::Negative(1));
|
||||
|
||||
assert_eq!(P_CT_2 / 2u64, P_CT_1);
|
||||
assert_eq!(N_CT_2 / 2u64, N_CT_1);
|
||||
|
||||
|
@ -594,6 +613,8 @@ mod tests {
|
|||
assert_eq!(N_CT_3 % 2i64, N_CT_1);
|
||||
assert_eq!(N_CT_3 % -2i64, N_CT_1);
|
||||
|
||||
assert_eq!(N_CT_3 % N_CT_2, N_CT_1);
|
||||
|
||||
assert_eq!(P_CT_3 % 2u64, P_CT_1);
|
||||
assert_eq!(N_CT_3 % 2u64, N_CT_1);
|
||||
}
|
||||
|
@ -611,8 +632,11 @@ mod tests {
|
|||
assert_eq!(CT_1.opt_checked_add(CT_1), Ok(Some(CT_2)));
|
||||
assert_eq!(CT_1.opt_checked_add(Some(CT_1)), Ok(Some(CT_2)));
|
||||
assert_eq!(Some(CT_1).opt_checked_add(Some(CT_1)), Ok(Some(CT_2)));
|
||||
assert_eq!(CT_1.opt_checked_add(None), Ok(None));
|
||||
assert_eq!(Some(CT_1).opt_checked_add(None), Ok(None));
|
||||
assert_eq!(CT_1.opt_checked_add(ClockTime::NONE), Ok(None));
|
||||
assert_eq!(Some(CT_1).opt_checked_add(ClockTime::NONE), Ok(None));
|
||||
|
||||
assert_eq!(CT_1.opt_checked_add(P_CT_1), Ok(Some(P_CT_2)));
|
||||
assert_eq!(N_CT_3.opt_checked_add(CT_1), Ok(Some(N_CT_2)));
|
||||
|
||||
assert!(ClockTime::MAX.checked_add(CT_1).is_none());
|
||||
assert_eq!(
|
||||
|
@ -623,8 +647,8 @@ mod tests {
|
|||
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!(P_CT_1.opt_checked_add(ClockTime::NONE), Ok(None));
|
||||
assert_eq!(Some(N_CT_1).opt_checked_add(ClockTime::NONE), Ok(None));
|
||||
|
||||
assert_eq!(
|
||||
ClockTime::MAX.into_positive().opt_checked_add(Some(P_CT_1)),
|
||||
|
@ -643,8 +667,11 @@ mod tests {
|
|||
assert_eq!(CT_2.opt_checked_sub(Some(CT_1)), Ok(Some(CT_1)));
|
||||
assert_eq!(Some(CT_2).opt_checked_sub(CT_1), Ok(Some(CT_1)));
|
||||
assert_eq!(Some(CT_2).opt_checked_sub(Some(CT_1)), Ok(Some(CT_1)));
|
||||
assert_eq!(CT_2.opt_checked_sub(None), Ok(None));
|
||||
assert_eq!(Some(CT_2).opt_checked_sub(None), Ok(None));
|
||||
assert_eq!(CT_2.opt_checked_sub(ClockTime::NONE), Ok(None));
|
||||
assert_eq!(Some(CT_2).opt_checked_sub(ClockTime::NONE), Ok(None));
|
||||
|
||||
assert_eq!(P_CT_2.opt_checked_sub(CT_1), Ok(Some(P_CT_1)));
|
||||
assert_eq!(N_CT_2.opt_checked_sub(CT_1), Ok(Some(N_CT_3)));
|
||||
|
||||
assert!(CT_1.checked_sub(CT_2).is_none());
|
||||
assert_eq!(
|
||||
|
@ -656,6 +683,8 @@ mod tests {
|
|||
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!(Some(CT_1).opt_checked_mul(2), Ok(Some(CT_2)));
|
||||
assert_eq!(1u64.opt_checked_mul(Some(CT_2)), Ok(Some(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!(N_CT_1.checked_mul(2), Some(N_CT_2));
|
||||
|
@ -664,6 +693,8 @@ mod tests {
|
|||
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!((-2i64).opt_checked_mul(Some(P_CT_1)), Ok(Some(N_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));
|
||||
|
||||
|
@ -673,6 +704,8 @@ mod tests {
|
|||
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!(Some(CT_3).opt_checked_div(CT_3), Ok(Some(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)));
|
||||
|
||||
|
@ -689,6 +722,7 @@ mod tests {
|
|||
Some(CT_1).opt_overflowing_add(Some(CT_2)),
|
||||
Some((CT_3, false))
|
||||
);
|
||||
|
||||
assert_eq!(ClockTime::NONE.opt_overflowing_add(CT_2), None);
|
||||
assert_eq!(CT_1.opt_overflowing_add(ClockTime::NONE), None);
|
||||
|
||||
|
@ -737,7 +771,10 @@ mod tests {
|
|||
|
||||
assert_eq!(CT_1.opt_saturating_add(Some(CT_2)), Some(CT_3));
|
||||
assert_eq!(Some(CT_1).opt_saturating_add(Some(CT_2)), Some(CT_3));
|
||||
assert_eq!(Some(CT_1).opt_saturating_add(None), None);
|
||||
assert_eq!(Some(CT_1).opt_saturating_add(ClockTime::NONE), None);
|
||||
|
||||
assert_eq!(P_CT_1.opt_saturating_add(Some(CT_2)), Some(P_CT_3));
|
||||
assert_eq!(Some(CT_1).opt_saturating_add(P_CT_2), Some(P_CT_3));
|
||||
|
||||
assert_eq!(ClockTime::MAX.saturating_add(CT_1), ClockTime::MAX);
|
||||
assert_eq!(
|
||||
|
@ -756,7 +793,10 @@ mod tests {
|
|||
|
||||
assert_eq!(CT_3.opt_saturating_sub(Some(CT_2)), Some(CT_1));
|
||||
assert_eq!(Some(CT_3).opt_saturating_sub(Some(CT_2)), Some(CT_1));
|
||||
assert_eq!(Some(CT_3).opt_saturating_sub(None), None);
|
||||
assert_eq!(Some(CT_3).opt_saturating_sub(ClockTime::NONE), None);
|
||||
|
||||
assert_eq!(P_CT_2.opt_saturating_sub(Some(CT_3)), Some(N_CT_1));
|
||||
assert_eq!(Some(CT_3).opt_saturating_sub(P_CT_2), Some(P_CT_1));
|
||||
|
||||
assert!(CT_1.saturating_sub(CT_2).is_zero());
|
||||
assert_eq!(P_CT_1.saturating_sub(P_CT_2), N_CT_1);
|
||||
|
@ -773,12 +813,18 @@ mod tests {
|
|||
assert_eq!(N_CT_1.saturating_mul(2), N_CT_2);
|
||||
assert_eq!(N_CT_1.saturating_mul(-2), P_CT_2);
|
||||
|
||||
assert_eq!(Some(N_CT_1).opt_saturating_mul(-2i64), Some(P_CT_2));
|
||||
assert_eq!((-2i64).opt_saturating_mul(Some(N_CT_1)), Some(P_CT_2));
|
||||
|
||||
assert_eq!(P_CT_1.saturating_mul_unsigned(2u64), P_CT_2);
|
||||
assert_eq!(N_CT_1.saturating_mul_unsigned(2u64), N_CT_2);
|
||||
|
||||
assert_eq!(p_ct_max.saturating_mul(2), p_ct_max);
|
||||
assert_eq!(n_ct_max.saturating_mul(2), n_ct_max);
|
||||
|
||||
assert_eq!(Some(2i64).opt_saturating_mul(p_ct_max), Some(p_ct_max));
|
||||
assert_eq!(2u64.opt_saturating_mul(Some(n_ct_max)), Some(n_ct_max));
|
||||
|
||||
assert_eq!(p_ct_max.saturating_mul_unsigned(2u64), p_ct_max);
|
||||
assert_eq!(n_ct_max.saturating_mul_unsigned(2u64), n_ct_max);
|
||||
}
|
||||
|
@ -801,7 +847,7 @@ mod tests {
|
|||
assert_eq!(CT_3.opt_wrapping_sub(CT_2), Some(CT_1));
|
||||
assert_eq!(Some(CT_3).opt_wrapping_sub(CT_2), Some(CT_1));
|
||||
assert_eq!(Some(CT_3).opt_wrapping_sub(Some(CT_2)), Some(CT_1));
|
||||
assert_eq!(Some(CT_3).opt_wrapping_sub(None), None);
|
||||
assert_eq!(Some(CT_3).opt_wrapping_sub(ClockTime::NONE), None);
|
||||
|
||||
assert_eq!(CT_1.wrapping_sub(CT_2), ClockTime::MAX);
|
||||
assert_eq!(
|
||||
|
@ -864,6 +910,9 @@ mod tests {
|
|||
assert!(ClockTime::ZERO < CT_3);
|
||||
assert!(Some(ClockTime::ZERO) < Some(CT_3));
|
||||
|
||||
assert_eq!(CT_2, CT_2);
|
||||
assert_ne!(CT_3, CT_2);
|
||||
|
||||
assert!(ClockTime::ZERO.into_positive() < P_CT_1);
|
||||
assert!(ClockTime::ZERO.into_positive() > N_CT_1);
|
||||
assert!(P_CT_1 < P_CT_2);
|
||||
|
@ -871,11 +920,35 @@ mod tests {
|
|||
assert!(N_CT_1 < P_CT_2);
|
||||
assert!(N_CT_3 < N_CT_2);
|
||||
|
||||
assert!(P_CT_1 < CT_2);
|
||||
assert!(CT_1 < P_CT_2);
|
||||
assert!(N_CT_2 < CT_1);
|
||||
assert!(CT_1 > N_CT_2);
|
||||
|
||||
assert_eq!(CT_2, P_CT_2);
|
||||
assert_ne!(N_CT_3, CT_3);
|
||||
|
||||
assert_eq!(Some(CT_2).opt_lt(Some(CT_3)), Some(true));
|
||||
assert_eq!(Some(CT_3).opt_lt(CT_2), Some(false));
|
||||
assert_eq!(Some(CT_2).opt_le(Some(CT_3)), Some(true));
|
||||
assert_eq!(Some(CT_3).opt_le(CT_3), Some(true));
|
||||
|
||||
assert_eq!(Some(P_CT_2).opt_lt(Some(P_CT_3)), Some(true));
|
||||
assert_eq!(Some(P_CT_3).opt_lt(P_CT_2), Some(false));
|
||||
assert_eq!(Some(P_CT_2).opt_le(Some(P_CT_3)), Some(true));
|
||||
assert_eq!(Some(P_CT_3).opt_le(P_CT_3), Some(true));
|
||||
|
||||
assert_eq!(Some(P_CT_0).opt_lt(P_CT_NONE), None);
|
||||
assert_eq!(P_CT_NONE.opt_lt(P_CT_0), None);
|
||||
|
||||
assert_eq!(Some(N_CT_3).opt_lt(Some(N_CT_2)), Some(true));
|
||||
assert_eq!(Some(N_CT_2).opt_lt(N_CT_3), Some(false));
|
||||
assert_eq!(Some(N_CT_3).opt_le(Some(N_CT_2)), Some(true));
|
||||
assert_eq!(Some(N_CT_3).opt_le(N_CT_3), Some(true));
|
||||
|
||||
assert_eq!(Some(P_CT_2).opt_lt(N_CT_3), Some(false));
|
||||
assert_eq!(Some(N_CT_3).opt_lt(Some(P_CT_2)), Some(true));
|
||||
|
||||
assert!(CT_3 > CT_2);
|
||||
assert!(Some(CT_3) > Some(CT_2));
|
||||
assert!(CT_2 > ClockTime::ZERO);
|
||||
|
@ -891,6 +964,20 @@ mod tests {
|
|||
assert_eq!(Some(CT_3).opt_ge(Some(CT_2)), Some(true));
|
||||
assert_eq!(Some(CT_3).opt_ge(CT_3), Some(true));
|
||||
|
||||
assert_eq!(Some(P_CT_3).opt_gt(Some(P_CT_2)), Some(true));
|
||||
assert_eq!(Some(P_CT_3).opt_ge(Some(P_CT_2)), Some(true));
|
||||
assert_eq!(Some(P_CT_3).opt_ge(P_CT_3), Some(true));
|
||||
|
||||
assert_eq!(Some(P_CT_0).opt_gt(P_CT_NONE), None);
|
||||
assert_eq!(P_CT_NONE.opt_gt(P_CT_0), None);
|
||||
|
||||
assert_eq!(Some(N_CT_3).opt_gt(Some(N_CT_2)), Some(false));
|
||||
assert_eq!(Some(N_CT_3).opt_ge(Some(N_CT_2)), Some(false));
|
||||
assert_eq!(Some(N_CT_3).opt_ge(N_CT_3), Some(true));
|
||||
|
||||
assert_eq!(Some(P_CT_2).opt_gt(N_CT_3), Some(true));
|
||||
assert_eq!(Some(N_CT_3).opt_gt(Some(P_CT_2)), Some(false));
|
||||
|
||||
assert!(!(ClockTime::NONE < None));
|
||||
assert!(!(ClockTime::NONE > None));
|
||||
|
||||
|
@ -914,11 +1001,23 @@ mod tests {
|
|||
assert_eq!(ClockTime::NONE.opt_min(Some(CT_2)), None);
|
||||
assert_eq!(Some(CT_3).opt_min(ClockTime::NONE), None);
|
||||
|
||||
assert_eq!(P_CT_3.opt_min(P_CT_2), Some(P_CT_2));
|
||||
assert_eq!(P_CT_2.opt_min(P_CT_3), Some(P_CT_2));
|
||||
assert_eq!(N_CT_3.opt_min(N_CT_2), Some(N_CT_3));
|
||||
assert_eq!(N_CT_2.opt_min(N_CT_3), Some(N_CT_3));
|
||||
assert_eq!(P_CT_2.opt_min(N_CT_3), Some(N_CT_3));
|
||||
|
||||
assert_eq!(CT_3.opt_max(CT_2), Some(CT_3));
|
||||
assert_eq!(CT_3.opt_max(Some(CT_2)), Some(CT_3));
|
||||
assert_eq!(Some(CT_3).opt_max(Some(CT_2)), Some(CT_3));
|
||||
assert_eq!(ClockTime::NONE.opt_max(Some(CT_2)), None);
|
||||
assert_eq!(Some(CT_3).opt_max(ClockTime::NONE), None);
|
||||
|
||||
assert_eq!(P_CT_3.opt_max(P_CT_2), Some(P_CT_3));
|
||||
assert_eq!(P_CT_2.opt_max(P_CT_3), Some(P_CT_3));
|
||||
assert_eq!(N_CT_3.opt_max(N_CT_2), Some(N_CT_2));
|
||||
assert_eq!(N_CT_2.opt_max(N_CT_3), Some(N_CT_2));
|
||||
assert_eq!(P_CT_2.opt_max(N_CT_3), Some(P_CT_2));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -106,14 +106,6 @@ macro_rules! impl_trait_op_inner_type(
|
|||
}
|
||||
}
|
||||
|
||||
impl std::ops::$op<$name> for $inner_type {
|
||||
type Output = $name;
|
||||
|
||||
fn $op_name(self, rhs: $name) -> $name {
|
||||
$name(self.$op_name(rhs.0))
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::$op_assign<$inner_type> for $name {
|
||||
fn $op_assign_name(&mut self, rhs: $inner_type) {
|
||||
self.0.$op_assign_name(rhs)
|
||||
|
@ -192,9 +184,9 @@ macro_rules! impl_non_trait_op_inner_type(
|
|||
);
|
||||
|
||||
macro_rules! impl_unsigned_int_into_signed(
|
||||
($name:ident) => {
|
||||
impl crate::UnsignedIntoSigned for $name {
|
||||
type Signed = crate::Signed<$name>;
|
||||
($type:ty) => {
|
||||
impl crate::UnsignedIntoSigned for $type {
|
||||
type Signed = crate::Signed<$type>;
|
||||
|
||||
fn into_positive(self) -> Self::Signed {
|
||||
crate::Signed::Positive(self)
|
||||
|
@ -205,8 +197,8 @@ macro_rules! impl_unsigned_int_into_signed(
|
|||
}
|
||||
}
|
||||
|
||||
impl crate::UnsignedIntoSigned for Option<$name> {
|
||||
type Signed = Option<crate::Signed<$name>>;
|
||||
impl crate::UnsignedIntoSigned for Option<$type> {
|
||||
type Signed = Option<crate::Signed<$type>>;
|
||||
|
||||
fn into_positive(self) -> Self::Signed {
|
||||
Some(self?.into_positive())
|
||||
|
@ -217,6 +209,22 @@ macro_rules! impl_unsigned_int_into_signed(
|
|||
}
|
||||
}
|
||||
};
|
||||
|
||||
($type:ty, $inner_type:ty) => {
|
||||
impl_unsigned_int_into_signed!($type);
|
||||
|
||||
impl crate::Signed<$type> {
|
||||
// rustdoc-stripper-ignore-next
|
||||
/// Returns a `Signed` containing the inner type of `self`.
|
||||
pub fn into_inner_signed(self) -> crate::Signed<$inner_type> {
|
||||
use crate::Signed::*;
|
||||
match self {
|
||||
Positive(new_type) => Positive(*new_type),
|
||||
Negative(new_type) => Negative(*new_type),
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
);
|
||||
|
||||
macro_rules! impl_common_ops_for_newtype_uint(
|
||||
|
@ -235,19 +243,39 @@ macro_rules! impl_common_ops_for_newtype_uint(
|
|||
|
||||
impl_trait_op_same!($name, Add, add, AddAssign, add_assign);
|
||||
impl_trait_op_same!($name, Sub, sub, SubAssign, sub_assign);
|
||||
impl_trait_op_same!($name, Mul, mul, MulAssign, mul_assign);
|
||||
impl_trait_op_same!($name, Div, div, DivAssign, div_assign);
|
||||
impl_trait_op_same!($name, Rem, rem, RemAssign, rem_assign);
|
||||
impl std::ops::Div<$name> for $name {
|
||||
type Output = $inner_type;
|
||||
|
||||
fn div(self, rhs: $name) -> $inner_type {
|
||||
self.0.div(rhs.0)
|
||||
}
|
||||
}
|
||||
impl std::ops::Rem<$name> for $name {
|
||||
type Output = Self;
|
||||
|
||||
fn rem(self, rhs: Self) -> Self {
|
||||
Self(self.0.rem(rhs.0))
|
||||
}
|
||||
}
|
||||
|
||||
impl_non_trait_op_same!($name, $inner_type);
|
||||
|
||||
impl_trait_op_inner_type!($name, $inner_type, Mul, mul, MulAssign, mul_assign);
|
||||
impl std::ops::Mul<$name> for $inner_type {
|
||||
type Output = $name;
|
||||
|
||||
fn mul(self, rhs: $name) -> $name {
|
||||
$name(self.mul(rhs.0))
|
||||
}
|
||||
}
|
||||
|
||||
impl_trait_op_inner_type!($name, $inner_type, Div, div, DivAssign, div_assign);
|
||||
impl_trait_op_inner_type!($name, $inner_type, Rem, rem, RemAssign, rem_assign);
|
||||
|
||||
impl_non_trait_op_inner_type!($name, $inner_type);
|
||||
|
||||
impl_unsigned_int_into_signed!($name);
|
||||
impl_unsigned_int_into_signed!($name, $inner_type);
|
||||
|
||||
impl_signed_ops!($name, $inner_type, $name::ZERO);
|
||||
|
||||
impl muldiv::MulDiv<$inner_type> for $name {
|
||||
|
@ -314,10 +342,23 @@ macro_rules! impl_common_ops_for_newtype_uint(
|
|||
if rhs == 0 {
|
||||
return Err(opt_ops::Error::DivisionByZero);
|
||||
}
|
||||
self.0
|
||||
self
|
||||
.checked_div(rhs)
|
||||
.ok_or(opt_ops::Error::Overflow)
|
||||
.map(|val| Some(Self(val)))
|
||||
.map(Some)
|
||||
}
|
||||
}
|
||||
|
||||
impl opt_ops::OptionCheckedDiv for $name {
|
||||
type Output = $inner_type;
|
||||
fn opt_checked_div(self, rhs: Self) -> Result<Option<Self::Output>, opt_ops::Error> {
|
||||
if rhs.0 == 0 {
|
||||
return Err(opt_ops::Error::DivisionByZero);
|
||||
}
|
||||
self.0
|
||||
.checked_div(rhs.0)
|
||||
.ok_or(opt_ops::Error::Overflow)
|
||||
.map(Some)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -333,6 +374,18 @@ macro_rules! impl_common_ops_for_newtype_uint(
|
|||
}
|
||||
}
|
||||
|
||||
impl opt_ops::OptionCheckedMul<$name> for $inner_type {
|
||||
type Output = $name;
|
||||
fn opt_checked_mul(
|
||||
self,
|
||||
rhs: $name,
|
||||
) -> Result<Option<Self::Output>, opt_ops::Error> {
|
||||
rhs.checked_mul(self)
|
||||
.ok_or(opt_ops::Error::Overflow)
|
||||
.map(Some)
|
||||
}
|
||||
}
|
||||
|
||||
impl opt_ops::OptionSaturatingMul<$inner_type> for $name {
|
||||
type Output = Self;
|
||||
fn opt_saturating_mul(self, rhs: $inner_type) -> Option<Self::Output> {
|
||||
|
@ -340,6 +393,13 @@ macro_rules! impl_common_ops_for_newtype_uint(
|
|||
}
|
||||
}
|
||||
|
||||
impl opt_ops::OptionSaturatingMul<$name> for $inner_type {
|
||||
type Output = $name;
|
||||
fn opt_saturating_mul(self, rhs: $name) -> Option<Self::Output> {
|
||||
Some(rhs.saturating_mul(self))
|
||||
}
|
||||
}
|
||||
|
||||
impl opt_ops::OptionOverflowingMul<$inner_type> for $name {
|
||||
type Output = Self;
|
||||
fn opt_overflowing_mul(self, rhs: $inner_type) -> Option<(Self::Output, bool)> {
|
||||
|
@ -348,6 +408,14 @@ macro_rules! impl_common_ops_for_newtype_uint(
|
|||
}
|
||||
}
|
||||
|
||||
impl opt_ops::OptionOverflowingMul<$name> for $inner_type {
|
||||
type Output = $name;
|
||||
fn opt_overflowing_mul(self, rhs: $name) -> Option<(Self::Output, bool)> {
|
||||
let res = rhs.overflowing_mul(self);
|
||||
Some((res.0, res.1))
|
||||
}
|
||||
}
|
||||
|
||||
impl opt_ops::OptionWrappingMul<$inner_type> for $name {
|
||||
type Output = Self;
|
||||
fn opt_wrapping_mul(self, rhs: $inner_type) -> Option<Self::Output> {
|
||||
|
@ -355,16 +423,34 @@ macro_rules! impl_common_ops_for_newtype_uint(
|
|||
}
|
||||
}
|
||||
|
||||
impl opt_ops::OptionWrappingMul<$name> for $inner_type {
|
||||
type Output = $name;
|
||||
fn opt_wrapping_mul(self, rhs: $name) -> Option<Self::Output> {
|
||||
Some(rhs.wrapping_mul(self))
|
||||
}
|
||||
}
|
||||
|
||||
impl opt_ops::OptionCheckedRem<$inner_type> for $name {
|
||||
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.0
|
||||
.checked_rem(rhs)
|
||||
self.checked_rem(rhs)
|
||||
.ok_or(opt_ops::Error::Overflow)
|
||||
.map(|val| Some(Self(val)))
|
||||
.map(Some)
|
||||
}
|
||||
}
|
||||
|
||||
impl opt_ops::OptionCheckedRem for $name {
|
||||
type Output = Self;
|
||||
fn opt_checked_rem(self, rhs: Self) -> Result<Option<Self::Output>, opt_ops::Error> {
|
||||
if rhs.0 == 0 {
|
||||
return Err(opt_ops::Error::DivisionByZero);
|
||||
}
|
||||
self.checked_rem(rhs.0)
|
||||
.ok_or(opt_ops::Error::Overflow)
|
||||
.map(Some)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -409,10 +495,6 @@ macro_rules! impl_signed_ops(
|
|||
impl_signed_ops!(u64, u64, 0);
|
||||
};
|
||||
|
||||
(usize) => {
|
||||
impl_signed_ops!(usize, usize, 0);
|
||||
};
|
||||
|
||||
(u32) => {
|
||||
impl_signed_ops!(u32, u32, 0);
|
||||
};
|
||||
|
@ -577,6 +659,20 @@ macro_rules! impl_signed_ops(
|
|||
}
|
||||
}
|
||||
|
||||
impl std::ops::Add<crate::Signed<$type>> for $type {
|
||||
type Output = crate::Signed<$type>;
|
||||
fn add(self, other: crate::Signed<$type>) -> crate::Signed<$type> {
|
||||
crate::Signed::Positive(self).checked_add(other).expect("Overflowing addition")
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::Sub<crate::Signed<$type>> for $type {
|
||||
type Output = crate::Signed<$type>;
|
||||
fn sub(self, other: crate::Signed<$type>) -> crate::Signed<$type> {
|
||||
crate::Signed::Positive(self).checked_sub(other).expect("Overflowing subtraction")
|
||||
}
|
||||
}
|
||||
|
||||
impl std::cmp::PartialOrd<crate::Signed<$type>> for crate::Signed<$type> {
|
||||
fn partial_cmp(&self, other: &crate::Signed<$type>) -> Option<std::cmp::Ordering> {
|
||||
Some(self.cmp(other))
|
||||
|
@ -589,12 +685,24 @@ macro_rules! impl_signed_ops(
|
|||
}
|
||||
}
|
||||
|
||||
impl std::cmp::PartialEq<crate::Signed<$type>> for $type {
|
||||
fn eq(&self, other: &crate::Signed<$type>) -> bool {
|
||||
crate::Signed::Positive(*self).eq(other)
|
||||
}
|
||||
}
|
||||
|
||||
impl std::cmp::PartialOrd<$type> for crate::Signed<$type> {
|
||||
fn partial_cmp(&self, other: &$type) -> Option<std::cmp::Ordering> {
|
||||
Some(self.cmp(&crate::Signed::Positive(*other)))
|
||||
}
|
||||
}
|
||||
|
||||
impl std::cmp::PartialOrd<crate::Signed<$type>> for $type {
|
||||
fn partial_cmp(&self, other: &crate::Signed<$type>) -> Option<std::cmp::Ordering> {
|
||||
Some(crate::Signed::Positive(*self).cmp(other))
|
||||
}
|
||||
}
|
||||
|
||||
impl std::cmp::Ord for crate::Signed<$type> {
|
||||
fn cmp(&self, other: &crate::Signed<$type>) -> std::cmp::Ordering {
|
||||
use crate::Signed::*;
|
||||
|
@ -646,32 +754,111 @@ macro_rules! impl_signed_ops(
|
|||
Some(self.saturating_sub(rhs))
|
||||
}
|
||||
}
|
||||
|
||||
impl opt_ops::OptionCheckedAdd<$type> for crate::Signed<$type> {
|
||||
type Output = Self;
|
||||
fn opt_checked_add(
|
||||
self,
|
||||
rhs: $type,
|
||||
) -> Result<Option<Self>, opt_ops::Error> {
|
||||
self.opt_checked_add(crate::Signed::Positive(rhs))
|
||||
}
|
||||
}
|
||||
|
||||
impl opt_ops::OptionSaturatingAdd<$type> for crate::Signed<$type> {
|
||||
type Output = Self;
|
||||
fn opt_saturating_add(self, rhs: $type) -> Option<Self> {
|
||||
self.opt_saturating_add(crate::Signed::Positive(rhs))
|
||||
}
|
||||
}
|
||||
|
||||
impl opt_ops::OptionCheckedSub<$type> for crate::Signed<$type> {
|
||||
type Output = Self;
|
||||
fn opt_checked_sub(
|
||||
self,
|
||||
rhs: $type,
|
||||
) -> Result<Option<Self>, opt_ops::Error> {
|
||||
self.opt_checked_sub(crate::Signed::Positive(rhs))
|
||||
}
|
||||
}
|
||||
|
||||
impl opt_ops::OptionSaturatingSub<$type> for crate::Signed<$type> {
|
||||
type Output = Self;
|
||||
fn opt_saturating_sub(self, rhs: $type) -> Option<Self> {
|
||||
self.opt_saturating_sub(crate::Signed::Positive(rhs))
|
||||
}
|
||||
}
|
||||
|
||||
impl opt_ops::OptionCheckedAdd<crate::Signed<$type>> for $type {
|
||||
type Output = crate::Signed<$type>;
|
||||
fn opt_checked_add(
|
||||
self,
|
||||
rhs: crate::Signed<$type>,
|
||||
) -> Result<Option<Self::Output>, opt_ops::Error> {
|
||||
crate::Signed::Positive(self).opt_checked_add(rhs)
|
||||
}
|
||||
}
|
||||
|
||||
impl opt_ops::OptionSaturatingAdd<crate::Signed<$type>> for $type {
|
||||
type Output = crate::Signed<$type>;
|
||||
fn opt_saturating_add(
|
||||
self,
|
||||
rhs: crate::Signed<$type>
|
||||
) -> Option<Self::Output> {
|
||||
crate::Signed::Positive(self).opt_saturating_add(rhs)
|
||||
}
|
||||
}
|
||||
|
||||
impl opt_ops::OptionCheckedSub<crate::Signed<$type>> for $type {
|
||||
type Output = crate::Signed<$type>;
|
||||
fn opt_checked_sub(
|
||||
self,
|
||||
rhs: crate::Signed<$type>,
|
||||
) -> Result<Option<Self::Output>, opt_ops::Error> {
|
||||
crate::Signed::Positive(self).opt_checked_sub(rhs)
|
||||
}
|
||||
}
|
||||
|
||||
impl opt_ops::OptionSaturatingSub<crate::Signed<$type>> for $type {
|
||||
type Output = crate::Signed<$type>;
|
||||
fn opt_saturating_sub(
|
||||
self,
|
||||
rhs: crate::Signed<$type>
|
||||
) -> Option<Self::Output> {
|
||||
crate::Signed::Positive(self).opt_saturating_sub(rhs)
|
||||
}
|
||||
}
|
||||
};
|
||||
);
|
||||
|
||||
macro_rules! impl_signed_div_mul(
|
||||
(u64) => {
|
||||
impl_signed_div_mul!(u64, u64, i64, |val: u64| val);
|
||||
impl_signed_extra_div_mul!(u64, i64);
|
||||
impl_signed_div_mul_trait!(u64, u64, i64, |val: u64| val);
|
||||
};
|
||||
|
||||
(usize) => {
|
||||
impl_signed_div_mul!(usize, usize, isize, |val: usize| val);
|
||||
impl_signed_extra_div_mul!(usize, isize);
|
||||
// `MulDiv` not available for usize
|
||||
};
|
||||
|
||||
(u32) => {
|
||||
impl_signed_div_mul!(u32, u32, i32, |val: u32| val);
|
||||
impl_signed_extra_div_mul!(u32, i32);
|
||||
impl_signed_div_mul_trait!(u32, u32, i32, |val: u32| val);
|
||||
};
|
||||
|
||||
($new_type:ty, u64) => {
|
||||
impl_signed_div_mul!($new_type, u64, i64, |val: $new_type| *val);
|
||||
impl_signed_extra_div_mul!($new_type, u64, i64);
|
||||
impl_signed_div_mul_trait!($new_type, u64, i64, |val: $new_type| *val);
|
||||
};
|
||||
|
||||
($new_type:ty, u32) => {
|
||||
impl_signed_div_mul!($new_type, u32, i32, |val: $new_type| *val);
|
||||
impl_signed_extra_div_mul!($new_type, u32, i32);
|
||||
impl_signed_div_mul_trait!($new_type, u32, i32, |val: $new_type| *val);
|
||||
};
|
||||
|
||||
|
@ -972,6 +1159,124 @@ macro_rules! impl_signed_div_mul(
|
|||
};
|
||||
);
|
||||
|
||||
macro_rules! impl_signed_extra_div_mul(
|
||||
($type:ty, $signed:ty) => {
|
||||
impl std::ops::Div for crate::Signed<$type> {
|
||||
type Output = Self;
|
||||
|
||||
fn div(self, rhs: Self) -> Self {
|
||||
match rhs {
|
||||
crate::Signed::Positive(rhs) => self.div(rhs),
|
||||
crate::Signed::Negative(rhs) => std::ops::Neg::neg(self.div(rhs)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::Rem for crate::Signed<$type> {
|
||||
type Output = Self;
|
||||
|
||||
fn rem(self, rhs: Self) -> Self {
|
||||
self.rem(rhs.abs())
|
||||
}
|
||||
}
|
||||
|
||||
impl opt_ops::OptionCheckedDiv for crate::Signed<$type> {
|
||||
type Output = Self;
|
||||
fn opt_checked_div(self, rhs: Self) -> Result<Option<Self::Output>, opt_ops::Error> {
|
||||
match rhs {
|
||||
crate::Signed::Positive(rhs) => self.opt_checked_div(rhs),
|
||||
crate::Signed::Negative(rhs) => {
|
||||
self.opt_checked_div(rhs)
|
||||
.map(|res| res.map(std::ops::Neg::neg))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl opt_ops::OptionCheckedRem for crate::Signed<$type> {
|
||||
type Output = Self;
|
||||
fn opt_checked_rem(self, rhs: Self) -> Result<Option<Self::Output>, opt_ops::Error> {
|
||||
self.opt_checked_rem(rhs.abs())
|
||||
}
|
||||
}
|
||||
};
|
||||
($new_type:ty, $inner_type:ty, $signed_innner_type:ty) => {
|
||||
impl std::ops::Div for crate::Signed<$new_type> {
|
||||
type Output = crate::Signed<$inner_type>;
|
||||
|
||||
fn div(self, rhs: Self) -> Self::Output {
|
||||
self.into_inner_signed().div(rhs.into_inner_signed())
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::Rem for crate::Signed<$new_type> {
|
||||
type Output = crate::Signed<$new_type>;
|
||||
|
||||
fn rem(self, rhs: Self) -> Self::Output {
|
||||
self.rem(rhs.abs().0)
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::Mul<crate::Signed<$new_type>> for $inner_type {
|
||||
type Output = crate::Signed<$new_type>;
|
||||
|
||||
fn mul(self, rhs: crate::Signed<$new_type>) -> Self::Output {
|
||||
rhs.mul(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::Mul<crate::Signed<$new_type>> for $signed_innner_type {
|
||||
type Output = crate::Signed<$new_type>;
|
||||
|
||||
fn mul(self, rhs: crate::Signed<$new_type>) -> Self::Output {
|
||||
rhs.mul(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl opt_ops::OptionCheckedDiv for crate::Signed<$new_type> {
|
||||
type Output = crate::Signed<$inner_type>;
|
||||
fn opt_checked_div(self, rhs: Self) -> Result<Option<Self::Output>, opt_ops::Error> {
|
||||
self.into_inner_signed().opt_checked_div(rhs.into_inner_signed())
|
||||
}
|
||||
}
|
||||
|
||||
impl opt_ops::OptionCheckedRem for crate::Signed<$new_type> {
|
||||
type Output = crate::Signed<$inner_type>;
|
||||
fn opt_checked_rem(self, rhs: Self) -> Result<Option<Self::Output>, opt_ops::Error> {
|
||||
self.into_inner_signed().opt_checked_rem(rhs.abs().0)
|
||||
}
|
||||
}
|
||||
|
||||
impl opt_ops::OptionCheckedMul<crate::Signed<$new_type>> for $signed_innner_type {
|
||||
type Output = crate::Signed<$new_type>;
|
||||
fn opt_checked_mul(self, rhs: crate::Signed<$new_type>) -> Result<Option<Self::Output>, opt_ops::Error> {
|
||||
rhs.opt_checked_mul(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl opt_ops::OptionSaturatingMul<crate::Signed<$new_type>> for $signed_innner_type {
|
||||
type Output = crate::Signed<$new_type>;
|
||||
fn opt_saturating_mul(self, rhs: crate::Signed<$new_type>) -> Option<Self::Output> {
|
||||
rhs.opt_saturating_mul(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl opt_ops::OptionCheckedMul<crate::Signed<$new_type>> for $inner_type {
|
||||
type Output = crate::Signed<$new_type>;
|
||||
fn opt_checked_mul(self, rhs: crate::Signed<$new_type>) -> Result<Option<Self::Output>, opt_ops::Error> {
|
||||
rhs.opt_checked_mul(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl opt_ops::OptionSaturatingMul<crate::Signed<$new_type>> for $inner_type {
|
||||
type Output = crate::Signed<$new_type>;
|
||||
fn opt_saturating_mul(self, rhs: crate::Signed<$new_type>) -> Option<Self::Output> {
|
||||
rhs.opt_saturating_mul(self)
|
||||
}
|
||||
}
|
||||
};
|
||||
);
|
||||
|
||||
macro_rules! impl_signed_div_mul_trait(
|
||||
($type:ty, $inner_type:ty, $signed_rhs:ty, $into_inner:expr) => {
|
||||
impl crate::Signed<$type> {
|
||||
|
|
|
@ -232,10 +232,6 @@ impl_unsigned_int_into_signed!(u64);
|
|||
impl_signed_ops!(u64);
|
||||
impl_signed_div_mul!(u64);
|
||||
|
||||
impl_unsigned_int_into_signed!(usize);
|
||||
impl_signed_ops!(usize);
|
||||
impl_signed_div_mul!(usize);
|
||||
|
||||
impl_unsigned_int_into_signed!(u32);
|
||||
impl_signed_ops!(u32);
|
||||
impl_signed_div_mul!(u32);
|
||||
|
|
|
@ -135,11 +135,11 @@ fn tutorial_main() -> Result<(), Error> {
|
|||
} else {
|
||||
Percent::ZERO
|
||||
} / Percent::MAX;
|
||||
if start.is_zero() && stop.is_zero() {
|
||||
if start == 0 && stop == 0 {
|
||||
continue;
|
||||
}
|
||||
let start_ = *((start * GRAPH_LENGTH as u32) / (stop - start));
|
||||
let stop_ = *((stop * GRAPH_LENGTH as u32) / (stop - start));
|
||||
let start_ = (start * GRAPH_LENGTH as u32) / (stop - start);
|
||||
let stop_ = (stop * GRAPH_LENGTH as u32) / (stop - start);
|
||||
for j in start_..stop_ {
|
||||
graph[j as usize] = b'-';
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue