From 960befb2f53ef6ccc61382b427872ea66f707f5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Laignel?= Date: Sun, 18 Sep 2022 17:03:07 +0200 Subject: [PATCH] gst/Signed: move signed ops macro to macro.rs This will help with the implementation of Signed muls & divs for `FormattedValue`s since we need to know about the inner types. --- gstreamer/src/format.rs | 195 ----------------------------------- gstreamer/src/macros.rs | 222 ++++++++++++++++++++++++++++++++++++++-- 2 files changed, 212 insertions(+), 205 deletions(-) diff --git a/gstreamer/src/format.rs b/gstreamer/src/format.rs index 7f1df04e7..d61521323 100644 --- a/gstreamer/src/format.rs +++ b/gstreamer/src/format.rs @@ -288,202 +288,7 @@ impl Signed { } } -macro_rules! impl_signed_ops( - ($type:ty, $zero:expr) => { - impl Signed<$type> { - // rustdoc-stripper-ignore-next - /// Returns the signum for this `Signed`. - /// - /// Returns: - /// - /// - `0` if the number is zero. - /// - `1` if the value must be considered as positive. - /// - `-1` if the value must be considered as negative. - pub fn signum(self) -> i32 { - match self { - Signed::Positive(val) | Signed::Negative(val) if val == $zero => 0i32, - Signed::Positive(_) => 1i32, - Signed::Negative(_) => -1i32, - } - } - - // rustdoc-stripper-ignore-next - /// Returns the checked subtraction `self - other`. - #[must_use = "this returns the result of the operation, without modifying the original"] - pub fn checked_sub(self, other: Self) -> Option { - match (self, other) { - (Signed::Positive(a), Signed::Positive(b)) if a >= b => Some(Signed::Positive(a - b)), - (Signed::Positive(a), Signed::Positive(b)) => Some(Signed::Negative(b - a)), - (Signed::Negative(a), Signed::Negative(b)) if a >= b => Some(Signed::Negative(a - b)), - (Signed::Negative(a), Signed::Negative(b)) => Some(Signed::Positive(b - a)), - (Signed::Positive(a), Signed::Negative(b)) => a.checked_add(b).map(Signed::Positive), - (Signed::Negative(a), Signed::Positive(b)) => a.checked_add(b).map(Signed::Negative), - } - } - - // rustdoc-stripper-ignore-next - /// Returns the checked subtraction `self - other`. - #[must_use = "this returns the result of the operation, without modifying the original"] - pub fn checked_sub_unsigned(self, other: $type) -> Option { - self.checked_sub(Signed::Positive(other)) - } - - // rustdoc-stripper-ignore-next - /// Returns the checked addition `self + other`. - #[must_use = "this returns the result of the operation, without modifying the original"] - pub fn checked_add(self, other: Self) -> Option { - match (self, other) { - (Signed::Positive(a), Signed::Positive(b)) => a.checked_add(b).map(Signed::Positive), - (Signed::Negative(a), Signed::Negative(b)) => a.checked_add(b).map(Signed::Negative), - (Signed::Positive(_), Signed::Negative(_)) => self.checked_sub(-other), - (Signed::Negative(_), Signed::Positive(_)) => Some(-((-self).checked_sub(other)?)) - } - } - - // rustdoc-stripper-ignore-next - /// Returns the checked addition `self + other`. - #[must_use = "this returns the result of the operation, without modifying the original"] - pub fn checked_add_unsigned(self, other: $type) -> Option { - self.checked_add(Signed::Positive(other)) - } - - // rustdoc-stripper-ignore-next - /// Returns the saturating subtraction `self - other`. - #[must_use = "this returns the result of the operation, without modifying the original"] - pub fn saturating_sub(self, other: Self) -> Self { - match (self, other) { - (Signed::Positive(a), Signed::Positive(b)) if a >= b => Signed::Positive(a - b), - (Signed::Positive(a), Signed::Positive(b)) => Signed::Negative(b - a), - (Signed::Negative(a), Signed::Negative(b)) if a >= b => Signed::Negative(a - b), - (Signed::Negative(a), Signed::Negative(b)) => Signed::Positive(b - a), - (Signed::Positive(a), Signed::Negative(b)) => Signed::Positive(a.saturating_add(b)), - (Signed::Negative(a), Signed::Positive(b)) => Signed::Negative(a.saturating_add(b)), - } - } - - // rustdoc-stripper-ignore-next - /// Returns the saturating subtraction `self - other`. - #[must_use = "this returns the result of the operation, without modifying the original"] - pub fn saturating_sub_unsigned(self, other: $type) -> Self { - self.saturating_sub(Signed::Positive(other)) - } - - // rustdoc-stripper-ignore-next - /// Returns the saturating addition `self + other`. - #[must_use = "this returns the result of the operation, without modifying the original"] - pub fn saturating_add(self, other: Self) -> Self { - match (self, other) { - (Signed::Positive(a), Signed::Positive(b)) => Signed::Positive(a.saturating_add(b)), - (Signed::Negative(a), Signed::Negative(b)) => Signed::Negative(a.saturating_add(b)), - (Signed::Positive(_), Signed::Negative(_)) => self.saturating_sub(-other), - (Signed::Negative(_), Signed::Positive(_)) => -((-self).saturating_sub(other)), - } - } - - // rustdoc-stripper-ignore-next - /// Returns the saturating addition `self + other`. - #[must_use = "this returns the result of the operation, without modifying the original"] - pub fn saturating_add_unsigned(self, other: $type) -> Self { - self.saturating_add(Signed::Positive(other)) - } - } - - impl std::ops::Add> for Signed<$type> { - type Output = Signed<$type>; - - fn add(self, other: Signed<$type>) -> Signed<$type> { - self.checked_add(other).expect("Overflowing addition") - } - } - - impl std::ops::AddAssign> for Signed<$type> { - fn add_assign(&mut self, other: Signed<$type>) { - *self = self.checked_add(other).expect("Overflowing addition") - } - } - - impl std::ops::Sub> for Signed<$type> { - type Output = Signed<$type>; - - fn sub(self, other: Signed<$type>) -> Signed<$type> { - self.checked_sub(other).expect("Overflowing subtraction") - } - } - - impl std::ops::SubAssign> for Signed<$type> { - fn sub_assign(&mut self, other: Signed<$type>) { - *self = self.checked_sub(other).expect("Overflowing subtraction") - } - } - - impl std::ops::Add<$type> for Signed<$type> { - type Output = Signed<$type>; - - fn add(self, other: $type) -> Signed<$type> { - self.checked_add(Signed::Positive(other)).expect("Overflowing addition") - } - } - - impl std::ops::AddAssign<$type> for Signed<$type> { - fn add_assign(&mut self, other: $type) { - *self = self.checked_add(Signed::Positive(other)).expect("Overflowing addition") - } - } - - impl std::ops::Sub<$type> for Signed<$type> { - type Output = Signed<$type>; - - fn sub(self, other: $type) -> Signed<$type> { - self.checked_sub(Signed::Positive(other)).expect("Overflowing subtraction") - } - } - - impl std::ops::SubAssign<$type> for Signed<$type> { - fn sub_assign(&mut self, other: $type) { - *self = self.checked_sub(Signed::Positive(other)).expect("Overflowing subtraction") - } - } - - impl From<$type> for Signed<$type> { - fn from(val: $type) -> Self { - skip_assert_initialized!(); - Signed::Positive(val) - } - } - - impl PartialOrd> for Signed<$type> { - fn partial_cmp(&self, other: &Signed<$type>) -> Option { - Some(self.cmp(other)) - } - } - - impl PartialEq<$type> for Signed<$type> { - fn eq(&self, other: &$type) -> bool { - self.eq(&Signed::Positive(*other)) - } - } - - impl PartialOrd<$type> for Signed<$type> { - fn partial_cmp(&self, other: &$type) -> Option { - Some(self.cmp(&Signed::Positive(*other))) - } - } - - impl Ord for Signed<$type> { - fn cmp(&self, other: &Signed<$type>) -> std::cmp::Ordering { - match (self, other) { - (Signed::Positive(a), Signed::Positive(b)) => a.cmp(b), - (Signed::Negative(a), Signed::Negative(b)) => b.cmp(a), - (Signed::Positive(_), Signed::Negative(_)) => std::cmp::Ordering::Greater, - (Signed::Negative(_), Signed::Positive(_)) => std::cmp::Ordering::Less, - } - } - } - }; -); - impl_signed_ops!(u64, 0); -impl_signed_ops!(ClockTime, ClockTime::ZERO); #[derive(PartialEq, Eq, Hash, Clone, Copy, Debug)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] diff --git a/gstreamer/src/macros.rs b/gstreamer/src/macros.rs index 9adc3c383..25818a1be 100644 --- a/gstreamer/src/macros.rs +++ b/gstreamer/src/macros.rs @@ -234,6 +234,8 @@ macro_rules! impl_common_ops_for_newtype_uint( impl_non_trait_op_inner_type!($name, $inner_type); + impl_signed_ops!($name, $name::ZERO); + impl> MulDiv for $name { type Output = $name; @@ -388,11 +390,211 @@ macro_rules! impl_common_ops_for_newtype_uint( }; ); +macro_rules! impl_signed_ops( + ($type:ty, $zero:expr) => { + impl crate::Signed<$type> { + // rustdoc-stripper-ignore-next + /// Returns the signum for this `Signed`. + /// + /// Returns: + /// + /// - `0` if the number is zero. + /// - `1` if the value must be considered as positive. + /// - `-1` if the value must be considered as negative. + pub fn signum(self) -> i32 { + use crate::Signed::*; + match self { + Positive(val) | Negative(val) if val == $zero => 0i32, + Positive(_) => 1i32, + Negative(_) => -1i32, + } + } + + // rustdoc-stripper-ignore-next + /// Returns the checked subtraction `self - other`. + #[must_use = "this returns the result of the operation, without modifying the original"] + pub fn checked_sub(self, other: Self) -> Option { + use crate::Signed::*; + match (self, other) { + (Positive(a), Positive(b)) if a >= b => Some(Positive(a - b)), + (Positive(a), Positive(b)) => Some(Negative(b - a)), + (Negative(a), Negative(b)) if a >= b => Some(Negative(a - b)), + (Negative(a), Negative(b)) => Some(Positive(b - a)), + (Positive(a), Negative(b)) => a.checked_add(b).map(Positive), + (Negative(a), Positive(b)) => a.checked_add(b).map(Negative), + } + } + + // rustdoc-stripper-ignore-next + /// Returns the checked subtraction `self - other`. + #[must_use = "this returns the result of the operation, without modifying the original"] + pub fn checked_sub_unsigned(self, other: $type) -> Option { + self.checked_sub(crate::Signed::Positive(other)) + } + + // rustdoc-stripper-ignore-next + /// Returns the checked addition `self + other`. + #[must_use = "this returns the result of the operation, without modifying the original"] + pub fn checked_add(self, other: Self) -> Option { + use crate::Signed::*; + match (self, other) { + (Positive(a), Positive(b)) => a.checked_add(b).map(Positive), + (Negative(a), Negative(b)) => a.checked_add(b).map(Negative), + (Positive(_), Negative(_)) => self.checked_sub(-other), + (Negative(_), Positive(_)) => Some(-((-self).checked_sub(other)?)) + } + } + + // rustdoc-stripper-ignore-next + /// Returns the checked addition `self + other`. + #[must_use = "this returns the result of the operation, without modifying the original"] + pub fn checked_add_unsigned(self, other: $type) -> Option { + self.checked_add(crate::Signed::Positive(other)) + } + + // rustdoc-stripper-ignore-next + /// Returns the saturating subtraction `self - other`. + #[must_use = "this returns the result of the operation, without modifying the original"] + pub fn saturating_sub(self, other: Self) -> Self { + use crate::Signed::*; + match (self, other) { + (Positive(a), Positive(b)) if a >= b => Positive(a - b), + (Positive(a), Positive(b)) => Negative(b - a), + (Negative(a), Negative(b)) if a >= b => Negative(a - b), + (Negative(a), Negative(b)) => Positive(b - a), + (Positive(a), Negative(b)) => Positive(a.saturating_add(b)), + (Negative(a), Positive(b)) => Negative(a.saturating_add(b)), + } + } + + // rustdoc-stripper-ignore-next + /// Returns the saturating subtraction `self - other`. + #[must_use = "this returns the result of the operation, without modifying the original"] + pub fn saturating_sub_unsigned(self, other: $type) -> Self { + self.saturating_sub(crate::Signed::Positive(other)) + } + + // rustdoc-stripper-ignore-next + /// Returns the saturating addition `self + other`. + #[must_use = "this returns the result of the operation, without modifying the original"] + pub fn saturating_add(self, other: Self) -> Self { + use crate::Signed::*; + match (self, other) { + (Positive(a), Positive(b)) => Positive(a.saturating_add(b)), + (Negative(a), Negative(b)) => Negative(a.saturating_add(b)), + (Positive(_), Negative(_)) => self.saturating_sub(-other), + (Negative(_), Positive(_)) => -((-self).saturating_sub(other)), + } + } + + // rustdoc-stripper-ignore-next + /// Returns the saturating addition `self + other`. + #[must_use = "this returns the result of the operation, without modifying the original"] + pub fn saturating_add_unsigned(self, other: $type) -> Self { + self.saturating_add(crate::Signed::Positive(other)) + } + } + + impl std::ops::Add> for crate::Signed<$type> { + type Output = crate::Signed<$type>; + + fn add(self, other: crate::Signed<$type>) -> crate::Signed<$type> { + self.checked_add(other).expect("Overflowing addition") + } + } + + impl std::ops::AddAssign> for crate::Signed<$type> { + fn add_assign(&mut self, other: crate::Signed<$type>) { + *self = self.checked_add(other).expect("Overflowing addition") + } + } + + impl std::ops::Sub> for crate::Signed<$type> { + type Output = crate::Signed<$type>; + + fn sub(self, other: crate::Signed<$type>) -> crate::Signed<$type> { + self.checked_sub(other).expect("Overflowing subtraction") + } + } + + impl std::ops::SubAssign> for crate::Signed<$type> { + fn sub_assign(&mut self, other: crate::Signed<$type>) { + *self = self.checked_sub(other).expect("Overflowing subtraction") + } + } + + impl std::ops::Add<$type> for crate::Signed<$type> { + type Output = crate::Signed<$type>; + + fn add(self, other: $type) -> crate::Signed<$type> { + self.checked_add(crate::Signed::Positive(other)).expect("Overflowing addition") + } + } + + impl std::ops::AddAssign<$type> for crate::Signed<$type> { + fn add_assign(&mut self, other: $type) { + *self = self.checked_add(crate::Signed::Positive(other)).expect("Overflowing addition") + } + } + + impl std::ops::Sub<$type> for crate::Signed<$type> { + type Output = crate::Signed<$type>; + + fn sub(self, other: $type) -> crate::Signed<$type> { + self.checked_sub(crate::Signed::Positive(other)).expect("Overflowing subtraction") + } + } + + impl std::ops::SubAssign<$type> for crate::Signed<$type> { + fn sub_assign(&mut self, other: $type) { + *self = self.checked_sub(crate::Signed::Positive(other)).expect("Overflowing subtraction") + } + } + + impl From<$type> for crate::Signed<$type> { + fn from(val: $type) -> Self { + skip_assert_initialized!(); + crate::Signed::Positive(val) + } + } + + impl PartialOrd> for crate::Signed<$type> { + fn partial_cmp(&self, other: &crate::Signed<$type>) -> Option { + Some(self.cmp(other)) + } + } + + impl PartialEq<$type> for crate::Signed<$type> { + fn eq(&self, other: &$type) -> bool { + self.eq(&crate::Signed::Positive(*other)) + } + } + + impl PartialOrd<$type> for crate::Signed<$type> { + fn partial_cmp(&self, other: &$type) -> Option { + Some(self.cmp(&crate::Signed::Positive(*other))) + } + } + + impl Ord for crate::Signed<$type> { + fn cmp(&self, other: &crate::Signed<$type>) -> std::cmp::Ordering { + use crate::Signed::*; + match (self, other) { + (Positive(a), Positive(b)) => a.cmp(b), + (Negative(a), Negative(b)) => b.cmp(a), + (Positive(_), Negative(_)) => std::cmp::Ordering::Greater, + (Negative(_), Positive(_)) => std::cmp::Ordering::Less, + } + } + } + }; +); + macro_rules! impl_format_value_traits( ($name:ident, $format:ident, $format_value:ident, $inner_type:ty) => { impl FormattedValue for Option<$name> { type FullRange = Option<$name>; - type Signed = Option>; + type Signed = Option>; fn default_format() -> Format { Format::$format @@ -406,12 +608,12 @@ macro_rules! impl_format_value_traits( IntoGlib::into_glib(self) as i64 } - fn into_positive(self) -> Option> { - Some(Signed::Positive(self?)) + fn into_positive(self) -> Option> { + Some(crate::Signed::Positive(self?)) } - fn into_negative(self) -> Option> { - Some(Signed::Negative(self?)) + fn into_negative(self) -> Option> { + Some(crate::Signed::Negative(self?)) } } @@ -437,7 +639,7 @@ macro_rules! impl_format_value_traits( } impl FormattedValue for $name { type FullRange = Option<$name>; - type Signed = Signed<$name>; + type Signed = crate::Signed<$name>; fn default_format() -> Format { Format::$format @@ -451,12 +653,12 @@ macro_rules! impl_format_value_traits( IntoGlib::into_glib(self) as i64 } - fn into_positive(self) -> Signed<$name> { - Signed::Positive(self) + fn into_positive(self) -> crate::Signed<$name> { + crate::Signed::Positive(self) } - fn into_negative(self) -> Signed<$name> { - Signed::Negative(self) + fn into_negative(self) -> crate::Signed<$name> { + crate::Signed::Negative(self) } }