Skip to content

Commit

Permalink
Rollup merge of rust-lang#126046 - davidzeng0:mixed_integer_ops_unsig…
Browse files Browse the repository at this point in the history
…ned_sub, r=Amanieu

Implement `mixed_integer_ops_unsigned_sub`

Implement rust-lang#126043

ACP: rust-lang/libs-team#386 [Accepted]
  • Loading branch information
matthiaskrgr authored Nov 13, 2024
2 parents a00df61 + 6a5a88e commit f3df2a2
Showing 1 changed file with 103 additions and 0 deletions.
103 changes: 103 additions & 0 deletions library/core/src/num/uint_macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -763,6 +763,33 @@ macro_rules! uint_impl {
}
}

/// Checked subtraction with a signed integer. Computes `self - rhs`,
/// returning `None` if overflow occurred.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// #![feature(mixed_integer_ops_unsigned_sub)]
#[doc = concat!("assert_eq!(1", stringify!($SelfT), ".checked_sub_signed(2), None);")]
#[doc = concat!("assert_eq!(1", stringify!($SelfT), ".checked_sub_signed(-2), Some(3));")]
#[doc = concat!("assert_eq!((", stringify!($SelfT), "::MAX - 2).checked_sub_signed(-4), None);")]
/// ```
#[unstable(feature = "mixed_integer_ops_unsigned_sub", issue = "126043")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
pub const fn checked_sub_signed(self, rhs: $SignedT) -> Option<Self> {
let (res, overflow) = self.overflowing_sub_signed(rhs);

if !overflow {
Some(res)
} else {
None
}
}

#[doc = concat!(
"Checked integer subtraction. Computes `self - rhs` and checks if the result fits into an [`",
stringify!($SignedT), "`], returning `None` if overflow occurred."
Expand Down Expand Up @@ -1793,6 +1820,35 @@ macro_rules! uint_impl {
intrinsics::saturating_sub(self, rhs)
}

/// Saturating integer subtraction. Computes `self` - `rhs`, saturating at
/// the numeric bounds instead of overflowing.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// #![feature(mixed_integer_ops_unsigned_sub)]
#[doc = concat!("assert_eq!(1", stringify!($SelfT), ".saturating_sub_signed(2), 0);")]
#[doc = concat!("assert_eq!(1", stringify!($SelfT), ".saturating_sub_signed(-2), 3);")]
#[doc = concat!("assert_eq!((", stringify!($SelfT), "::MAX - 2).saturating_sub_signed(-4), ", stringify!($SelfT), "::MAX);")]
/// ```
#[unstable(feature = "mixed_integer_ops_unsigned_sub", issue = "126043")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
pub const fn saturating_sub_signed(self, rhs: $SignedT) -> Self {
let (res, overflow) = self.overflowing_sub_signed(rhs);

if !overflow {
res
} else if rhs < 0 {
Self::MAX
} else {
0
}
}

/// Saturating integer multiplication. Computes `self * rhs`,
/// saturating at the numeric bounds instead of overflowing.
///
Expand Down Expand Up @@ -1926,6 +1982,27 @@ macro_rules! uint_impl {
intrinsics::wrapping_sub(self, rhs)
}

/// Wrapping (modular) subtraction with a signed integer. Computes
/// `self - rhs`, wrapping around at the boundary of the type.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// #![feature(mixed_integer_ops_unsigned_sub)]
#[doc = concat!("assert_eq!(1", stringify!($SelfT), ".wrapping_sub_signed(2), ", stringify!($SelfT), "::MAX);")]
#[doc = concat!("assert_eq!(1", stringify!($SelfT), ".wrapping_sub_signed(-2), 3);")]
#[doc = concat!("assert_eq!((", stringify!($SelfT), "::MAX - 2).wrapping_sub_signed(-4), 1);")]
/// ```
#[unstable(feature = "mixed_integer_ops_unsigned_sub", issue = "126043")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
pub const fn wrapping_sub_signed(self, rhs: $SignedT) -> Self {
self.wrapping_sub(rhs as Self)
}

/// Wrapping (modular) multiplication. Computes `self *
/// rhs`, wrapping around at the boundary of the type.
///
Expand Down Expand Up @@ -2378,6 +2455,32 @@ macro_rules! uint_impl {
(c, b || d)
}

/// Calculates `self` - `rhs` with a signed `rhs`
///
/// Returns a tuple of the subtraction along with a boolean indicating
/// whether an arithmetic overflow would occur. If an overflow would
/// have occurred then the wrapped value is returned.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// #![feature(mixed_integer_ops_unsigned_sub)]
#[doc = concat!("assert_eq!(1", stringify!($SelfT), ".overflowing_sub_signed(2), (", stringify!($SelfT), "::MAX, true));")]
#[doc = concat!("assert_eq!(1", stringify!($SelfT), ".overflowing_sub_signed(-2), (3, false));")]
#[doc = concat!("assert_eq!((", stringify!($SelfT), "::MAX - 2).overflowing_sub_signed(-4), (1, true));")]
/// ```
#[unstable(feature = "mixed_integer_ops_unsigned_sub", issue = "126043")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
pub const fn overflowing_sub_signed(self, rhs: $SignedT) -> (Self, bool) {
let (res, overflow) = self.overflowing_sub(rhs as Self);

(res, overflow ^ (rhs < 0))
}

/// Computes the absolute difference between `self` and `other`.
///
/// # Examples
Expand Down

0 comments on commit f3df2a2

Please sign in to comment.