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.
This commit is contained in:
François Laignel 2022-09-18 17:03:07 +02:00 committed by François Laignel
parent 0d229b4c69
commit 960befb2f5
2 changed files with 212 additions and 205 deletions

View file

@ -288,202 +288,7 @@ impl Signed<ClockTime> {
}
}
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<Self> {
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> {
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<Self> {
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> {
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<Signed<$type>> 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<Signed<$type>> for Signed<$type> {
fn add_assign(&mut self, other: Signed<$type>) {
*self = self.checked_add(other).expect("Overflowing addition")
}
}
impl std::ops::Sub<Signed<$type>> 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<Signed<$type>> 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<Signed<$type>> for Signed<$type> {
fn partial_cmp(&self, other: &Signed<$type>) -> Option<std::cmp::Ordering> {
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<std::cmp::Ordering> {
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))]

View file

@ -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<ND: Borrow<$inner_type>> MulDiv<ND> 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<Self> {
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> {
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<Self> {
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> {
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<crate::Signed<$type>> 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<crate::Signed<$type>> 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<crate::Signed<$type>> 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<crate::Signed<$type>> 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<crate::Signed<$type>> for crate::Signed<$type> {
fn partial_cmp(&self, other: &crate::Signed<$type>) -> Option<std::cmp::Ordering> {
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<std::cmp::Ordering> {
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<Signed<$name>>;
type Signed = Option<crate::Signed<$name>>;
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<Signed<$name>> {
Some(Signed::Positive(self?))
fn into_positive(self) -> Option<crate::Signed<$name>> {
Some(crate::Signed::Positive(self?))
}
fn into_negative(self) -> Option<Signed<$name>> {
Some(Signed::Negative(self?))
fn into_negative(self) -> Option<crate::Signed<$name>> {
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)
}
}