Rollup merge of #126046 - davidzeng0:mixed_integer_ops_unsigned_sub, r=Amanieu

Implement `mixed_integer_ops_unsigned_sub`

Implement https://github.com/rust-lang/rust/issues/126043

ACP: https://github.com/rust-lang/libs-team/issues/386 [Accepted]
This commit is contained in:
Matthias Krüger 2024-11-13 21:04:22 +01:00 committed by GitHub
commit f3df2a2126
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -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."
@ -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.
///
@ -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.
///
@ -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