Auto merge of #30466 - alexcrichton:move-wrapping-and-fill-out, r=aturon
This commit migrates all of the methods on `num::wrapping::OverflowingOps` onto inherent methods of the integer types. This also fills out some missing gaps in the saturating and checked departments such as: * `saturating_mul` * `checked_{neg,rem,shl,shr}` This is done in preparation for stabilization, cc #27755
This commit is contained in:
commit
9f6917d426
@ -124,7 +124,7 @@ macro_rules! checked_op {
|
||||
|
||||
// `Int` + `SignedInt` implemented for signed integers
|
||||
macro_rules! int_impl {
|
||||
($ActualT:ty, $UnsignedT:ty, $BITS:expr,
|
||||
($ActualT:ident, $UnsignedT:ty, $BITS:expr,
|
||||
$add_with_overflow:path,
|
||||
$sub_with_overflow:path,
|
||||
$mul_with_overflow:path) => {
|
||||
@ -393,7 +393,8 @@ pub fn to_le(self) -> Self {
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn checked_add(self, other: Self) -> Option<Self> {
|
||||
checked_op!($ActualT, $add_with_overflow, self, other)
|
||||
let (a, b) = self.overflowing_add(other);
|
||||
if b {None} else {Some(a)}
|
||||
}
|
||||
|
||||
/// Checked integer subtraction. Computes `self - other`, returning
|
||||
@ -410,7 +411,8 @@ pub fn checked_add(self, other: Self) -> Option<Self> {
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn checked_sub(self, other: Self) -> Option<Self> {
|
||||
checked_op!($ActualT, $sub_with_overflow, self, other)
|
||||
let (a, b) = self.overflowing_sub(other);
|
||||
if b {None} else {Some(a)}
|
||||
}
|
||||
|
||||
/// Checked integer multiplication. Computes `self * other`, returning
|
||||
@ -427,7 +429,8 @@ pub fn checked_sub(self, other: Self) -> Option<Self> {
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn checked_mul(self, other: Self) -> Option<Self> {
|
||||
checked_op!($ActualT, $mul_with_overflow, self, other)
|
||||
let (a, b) = self.overflowing_mul(other);
|
||||
if b {None} else {Some(a)}
|
||||
}
|
||||
|
||||
/// Checked integer division. Computes `self / other`, returning `None`
|
||||
@ -445,14 +448,103 @@ pub fn checked_mul(self, other: Self) -> Option<Self> {
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn checked_div(self, other: Self) -> Option<Self> {
|
||||
match other {
|
||||
0 => None,
|
||||
-1 if self == Self::min_value()
|
||||
=> None,
|
||||
other => Some(self / other),
|
||||
if other == 0 {
|
||||
None
|
||||
} else {
|
||||
let (a, b) = self.overflowing_div(other);
|
||||
if b {None} else {Some(a)}
|
||||
}
|
||||
}
|
||||
|
||||
/// Checked integer remainder. Computes `self % other`, returning `None`
|
||||
/// if `other == 0` or the operation results in underflow or overflow.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(wrapping)]
|
||||
///
|
||||
/// use std::i32;
|
||||
///
|
||||
/// assert_eq!(5i32.checked_rem(2), Some(1));
|
||||
/// assert_eq!(5i32.checked_rem(0), None);
|
||||
/// assert_eq!(i32::MIN.checked_rem(-1), None);
|
||||
/// ```
|
||||
#[unstable(feature = "wrapping", issue = "27755")]
|
||||
#[inline]
|
||||
pub fn checked_rem(self, other: Self) -> Option<Self> {
|
||||
if other == 0 {
|
||||
None
|
||||
} else {
|
||||
let (a, b) = self.overflowing_rem(other);
|
||||
if b {None} else {Some(a)}
|
||||
}
|
||||
}
|
||||
|
||||
/// Checked negation. Computes `!self`, returning `None` if `self ==
|
||||
/// MIN`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(wrapping)]
|
||||
///
|
||||
/// use std::i32;
|
||||
///
|
||||
/// assert_eq!(5i32.checked_neg(), Some(-5));
|
||||
/// assert_eq!(i32::MIN.checked_neg(), None);
|
||||
/// ```
|
||||
#[unstable(feature = "wrapping", issue = "27755")]
|
||||
#[inline]
|
||||
pub fn checked_neg(self) -> Option<Self> {
|
||||
let (a, b) = self.overflowing_neg();
|
||||
if b {None} else {Some(a)}
|
||||
}
|
||||
|
||||
/// Checked shift left. Computes `self << rhs`, returning `None`
|
||||
/// if `rhs` is larger than or equal to the number of bits in `self`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(wrapping)]
|
||||
///
|
||||
/// assert_eq!(0x10i32.checked_shl(4), Some(0x100));
|
||||
/// assert_eq!(0x10i32.checked_shl(33), None);
|
||||
/// ```
|
||||
#[unstable(feature = "wrapping", issue = "27755")]
|
||||
#[inline]
|
||||
pub fn checked_shl(self, rhs: u32) -> Option<Self> {
|
||||
let (a, b) = self.overflowing_shl(rhs);
|
||||
if b {None} else {Some(a)}
|
||||
}
|
||||
|
||||
/// Checked shift right. Computes `self >> rhs`, returning `None`
|
||||
/// if `rhs` is larger than or equal to the number of bits in `self`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(wrapping)]
|
||||
///
|
||||
/// assert_eq!(0x10i32.checked_shr(4), Some(0x1));
|
||||
/// assert_eq!(0x10i32.checked_shr(33), None);
|
||||
/// ```
|
||||
#[unstable(feature = "wrapping", issue = "27755")]
|
||||
#[inline]
|
||||
pub fn checked_shr(self, rhs: u32) -> Option<Self> {
|
||||
let (a, b) = self.overflowing_shr(rhs);
|
||||
if b {None} else {Some(a)}
|
||||
}
|
||||
|
||||
/// Saturating integer addition. Computes `self + other`, saturating at
|
||||
/// the numeric bounds instead of overflowing.
|
||||
///
|
||||
@ -468,7 +560,7 @@ pub fn checked_div(self, other: Self) -> Option<Self> {
|
||||
#[inline]
|
||||
pub fn saturating_add(self, other: Self) -> Self {
|
||||
match self.checked_add(other) {
|
||||
Some(x) => x,
|
||||
Some(x) => x,
|
||||
None if other >= Self::zero() => Self::max_value(),
|
||||
None => Self::min_value(),
|
||||
}
|
||||
@ -489,12 +581,40 @@ pub fn saturating_add(self, other: Self) -> Self {
|
||||
#[inline]
|
||||
pub fn saturating_sub(self, other: Self) -> Self {
|
||||
match self.checked_sub(other) {
|
||||
Some(x) => x,
|
||||
Some(x) => x,
|
||||
None if other >= Self::zero() => Self::min_value(),
|
||||
None => Self::max_value(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Saturating integer multiplication. Computes `self * other`,
|
||||
/// saturating at the numeric bounds instead of overflowing.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(wrapping)]
|
||||
///
|
||||
/// use std::i32;
|
||||
///
|
||||
/// assert_eq!(100i32.saturating_mul(127), 12700);
|
||||
/// assert_eq!((1i32 << 23).saturating_mul(1 << 23), i32::MAX);
|
||||
/// assert_eq!((-1i32 << 23).saturating_mul(1 << 23), i32::MIN);
|
||||
/// ```
|
||||
#[unstable(feature = "wrapping", issue = "27755")]
|
||||
#[inline]
|
||||
pub fn saturating_mul(self, other: Self) -> Self {
|
||||
self.checked_mul(other).unwrap_or_else(|| {
|
||||
if (self < 0 && other < 0) || (self > 0 && other > 0) {
|
||||
Self::max_value()
|
||||
} else {
|
||||
Self::min_value()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// Wrapping (modular) addition. Computes `self + other`,
|
||||
/// wrapping around at the boundary of the type.
|
||||
///
|
||||
@ -562,6 +682,10 @@ pub fn wrapping_mul(self, rhs: Self) -> Self {
|
||||
/// in the type. In such a case, this function returns `MIN`
|
||||
/// itself.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function will panic if `rhs` is 0.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
@ -584,6 +708,10 @@ pub fn wrapping_div(self, rhs: Self) -> Self {
|
||||
/// -1` on a signed type (where `MIN` is the negative
|
||||
/// minimal value). In such a case, this function returns `0`.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function will panic if `rhs` is 0.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
@ -657,6 +785,230 @@ pub fn wrapping_shr(self, rhs: u32) -> Self {
|
||||
self.overflowing_shr(rhs).0
|
||||
}
|
||||
|
||||
/// Calculates `self` + `rhs`
|
||||
///
|
||||
/// Returns a tuple of the addition 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(wrapping)]
|
||||
///
|
||||
/// use std::i32;
|
||||
///
|
||||
/// assert_eq!(5i32.overflowing_add(2), (7, false));
|
||||
/// assert_eq!(i32::MAX.overflowing_add(1), (i32::MIN, true));
|
||||
/// ```
|
||||
#[inline]
|
||||
#[unstable(feature = "wrapping", issue = "27755")]
|
||||
pub fn overflowing_add(self, rhs: Self) -> (Self, bool) {
|
||||
unsafe {
|
||||
let (a, b) = $add_with_overflow(self as $ActualT,
|
||||
rhs as $ActualT);
|
||||
(a as Self, b)
|
||||
}
|
||||
}
|
||||
|
||||
/// Calculates `self` - `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(wrapping)]
|
||||
///
|
||||
/// use std::i32;
|
||||
///
|
||||
/// assert_eq!(5i32.overflowing_sub(2), (3, false));
|
||||
/// assert_eq!(i32::MIN.overflowing_sub(1), (i32::MAX, true));
|
||||
/// ```
|
||||
#[inline]
|
||||
#[unstable(feature = "wrapping", issue = "27755")]
|
||||
pub fn overflowing_sub(self, rhs: Self) -> (Self, bool) {
|
||||
unsafe {
|
||||
let (a, b) = $sub_with_overflow(self as $ActualT,
|
||||
rhs as $ActualT);
|
||||
(a as Self, b)
|
||||
}
|
||||
}
|
||||
|
||||
/// Calculates the multiplication of `self` and `rhs`.
|
||||
///
|
||||
/// Returns a tuple of the multiplication 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(wrapping)]
|
||||
///
|
||||
/// assert_eq!(5i32.overflowing_mul(2), (10, false));
|
||||
/// assert_eq!(1_000_000_000i32.overflowing_mul(10), (1410065408, true));
|
||||
/// ```
|
||||
#[inline]
|
||||
#[unstable(feature = "wrapping", issue = "27755")]
|
||||
pub fn overflowing_mul(self, rhs: Self) -> (Self, bool) {
|
||||
unsafe {
|
||||
let (a, b) = $mul_with_overflow(self as $ActualT,
|
||||
rhs as $ActualT);
|
||||
(a as Self, b)
|
||||
}
|
||||
}
|
||||
|
||||
/// Calculates the divisor when `self` is divided by `rhs`.
|
||||
///
|
||||
/// Returns a tuple of the divisor along with a boolean indicating
|
||||
/// whether an arithmetic overflow would occur. If an overflow would
|
||||
/// occur then self is returned.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function will panic if `rhs` is 0.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(wrapping)]
|
||||
///
|
||||
/// use std::i32;
|
||||
///
|
||||
/// assert_eq!(5i32.overflowing_div(2), (2, false));
|
||||
/// assert_eq!(i32::MIN.overflowing_div(-1), (i32::MIN, true));
|
||||
/// ```
|
||||
#[inline]
|
||||
#[unstable(feature = "wrapping", issue = "27755")]
|
||||
pub fn overflowing_div(self, rhs: Self) -> (Self, bool) {
|
||||
if self == Self::min_value() && rhs == -1 {
|
||||
(self, true)
|
||||
} else {
|
||||
(self / rhs, false)
|
||||
}
|
||||
}
|
||||
|
||||
/// Calculates the remainder when `self` is divided by `rhs`.
|
||||
///
|
||||
/// Returns a tuple of the remainder after dividing along with a boolean
|
||||
/// indicating whether an arithmetic overflow would occur. If an
|
||||
/// overflow would occur then 0 is returned.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function will panic if `rhs` is 0.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(wrapping)]
|
||||
///
|
||||
/// use std::i32;
|
||||
///
|
||||
/// assert_eq!(5i32.overflowing_rem(2), (1, false));
|
||||
/// assert_eq!(i32::MIN.overflowing_rem(-1), (0, true));
|
||||
/// ```
|
||||
#[inline]
|
||||
#[unstable(feature = "wrapping", issue = "27755")]
|
||||
pub fn overflowing_rem(self, rhs: Self) -> (Self, bool) {
|
||||
if self == Self::min_value() && rhs == -1 {
|
||||
(0, true)
|
||||
} else {
|
||||
(self % rhs, false)
|
||||
}
|
||||
}
|
||||
|
||||
/// Negates self, overflowing if this is equal to the minimum value.
|
||||
///
|
||||
/// Returns a tuple of the negated version of self along with a boolean
|
||||
/// indicating whether an overflow happened. If `self` is the minimum
|
||||
/// value (e.g. `i32::MIN` for values of type `i32`), then the minimum
|
||||
/// value will be returned again and `true` will be returned for an
|
||||
/// overflow happening.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(wrapping)]
|
||||
///
|
||||
/// use std::i32;
|
||||
///
|
||||
/// assert_eq!(2i32.overflowing_neg(), (-2, false));
|
||||
/// assert_eq!(i32::MIN.overflowing_neg(), (i32::MIN, true));
|
||||
/// ```
|
||||
#[inline]
|
||||
#[unstable(feature = "wrapping", issue = "27755")]
|
||||
pub fn overflowing_neg(self) -> (Self, bool) {
|
||||
if self == Self::min_value() {
|
||||
(Self::min_value(), true)
|
||||
} else {
|
||||
(-self, false)
|
||||
}
|
||||
}
|
||||
|
||||
/// Shifts self left by `rhs` bits.
|
||||
///
|
||||
/// Returns a tuple of the shifted version of self along with a boolean
|
||||
/// indicating whether the shift value was larger than or equal to the
|
||||
/// number of bits. If the shift value is too large, then value is
|
||||
/// masked (N-1) where N is the number of bits, and this value is then
|
||||
/// used to perform the shift.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(wrapping)]
|
||||
///
|
||||
/// assert_eq!(0x10i32.overflowing_shl(4), (0x100, false));
|
||||
/// assert_eq!(0x10i32.overflowing_shl(36), (0x100, true));
|
||||
/// ```
|
||||
#[inline]
|
||||
#[unstable(feature = "wrapping", issue = "27755")]
|
||||
pub fn overflowing_shl(self, rhs: u32) -> (Self, bool) {
|
||||
(self << (rhs & ($BITS - 1)), (rhs > ($BITS - 1)))
|
||||
}
|
||||
|
||||
/// Shifts self right by `rhs` bits.
|
||||
///
|
||||
/// Returns a tuple of the shifted version of self along with a boolean
|
||||
/// indicating whether the shift value was larger than or equal to the
|
||||
/// number of bits. If the shift value is too large, then value is
|
||||
/// masked (N-1) where N is the number of bits, and this value is then
|
||||
/// used to perform the shift.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(wrapping)]
|
||||
///
|
||||
/// assert_eq!(0x10i32.overflowing_shr(4), (0x1, false));
|
||||
/// assert_eq!(0x10i32.overflowing_shr(36), (0x1, true));
|
||||
/// ```
|
||||
#[inline]
|
||||
#[unstable(feature = "wrapping", issue = "27755")]
|
||||
pub fn overflowing_shr(self, rhs: u32) -> (Self, bool) {
|
||||
(self >> (rhs & ($BITS - 1)), (rhs > ($BITS - 1)))
|
||||
}
|
||||
|
||||
/// Raises self to the power of `exp`, using exponentiation by squaring.
|
||||
///
|
||||
/// # Examples
|
||||
@ -1121,7 +1473,8 @@ pub fn to_le(self) -> Self {
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn checked_add(self, other: Self) -> Option<Self> {
|
||||
checked_op!($ActualT, $add_with_overflow, self, other)
|
||||
let (a, b) = self.overflowing_add(other);
|
||||
if b {None} else {Some(a)}
|
||||
}
|
||||
|
||||
/// Checked integer subtraction. Computes `self - other`, returning
|
||||
@ -1138,7 +1491,8 @@ pub fn checked_add(self, other: Self) -> Option<Self> {
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn checked_sub(self, other: Self) -> Option<Self> {
|
||||
checked_op!($ActualT, $sub_with_overflow, self, other)
|
||||
let (a, b) = self.overflowing_sub(other);
|
||||
if b {None} else {Some(a)}
|
||||
}
|
||||
|
||||
/// Checked integer multiplication. Computes `self * other`, returning
|
||||
@ -1155,7 +1509,8 @@ pub fn checked_sub(self, other: Self) -> Option<Self> {
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn checked_mul(self, other: Self) -> Option<Self> {
|
||||
checked_op!($ActualT, $mul_with_overflow, self, other)
|
||||
let (a, b) = self.overflowing_mul(other);
|
||||
if b {None} else {Some(a)}
|
||||
}
|
||||
|
||||
/// Checked integer division. Computes `self / other`, returning `None`
|
||||
@ -1179,6 +1534,69 @@ pub fn checked_div(self, other: Self) -> Option<Self> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Checked integer remainder. Computes `self % other`, returning `None`
|
||||
/// if `other == 0` or the operation results in underflow or overflow.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(wrapping)]
|
||||
///
|
||||
/// assert_eq!(5u32.checked_rem(2), Some(1));
|
||||
/// assert_eq!(5u32.checked_rem(0), None);
|
||||
/// ```
|
||||
#[unstable(feature = "wrapping", issue = "27755")]
|
||||
#[inline]
|
||||
pub fn checked_rem(self, other: Self) -> Option<Self> {
|
||||
if other == 0 {
|
||||
None
|
||||
} else {
|
||||
Some(self % other)
|
||||
}
|
||||
}
|
||||
|
||||
/// Checked shift left. Computes `self << rhs`, returning `None`
|
||||
/// if `rhs` is larger than or equal to the number of bits in `self`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(wrapping)]
|
||||
///
|
||||
/// assert_eq!(0x10u32.checked_shl(4), Some(0x100));
|
||||
/// assert_eq!(0x10u32.checked_shl(33), None);
|
||||
/// ```
|
||||
#[unstable(feature = "wrapping", issue = "27755")]
|
||||
#[inline]
|
||||
pub fn checked_shl(self, rhs: u32) -> Option<Self> {
|
||||
let (a, b) = self.overflowing_shl(rhs);
|
||||
if b {None} else {Some(a)}
|
||||
}
|
||||
|
||||
/// Checked shift right. Computes `self >> rhs`, returning `None`
|
||||
/// if `rhs` is larger than or equal to the number of bits in `self`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(wrapping)]
|
||||
///
|
||||
/// assert_eq!(0x10u32.checked_shr(4), Some(0x1));
|
||||
/// assert_eq!(0x10u32.checked_shr(33), None);
|
||||
/// ```
|
||||
#[unstable(feature = "wrapping", issue = "27755")]
|
||||
#[inline]
|
||||
pub fn checked_shr(self, rhs: u32) -> Option<Self> {
|
||||
let (a, b) = self.overflowing_shr(rhs);
|
||||
if b {None} else {Some(a)}
|
||||
}
|
||||
|
||||
/// Saturating integer addition. Computes `self + other`, saturating at
|
||||
/// the numeric bounds instead of overflowing.
|
||||
///
|
||||
@ -1221,6 +1639,27 @@ pub fn saturating_sub(self, other: Self) -> Self {
|
||||
}
|
||||
}
|
||||
|
||||
/// Saturating integer multiplication. Computes `self * other`,
|
||||
/// saturating at the numeric bounds instead of overflowing.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(wrapping)]
|
||||
///
|
||||
/// use std::u32;
|
||||
///
|
||||
/// assert_eq!(100u32.saturating_mul(127), 12700);
|
||||
/// assert_eq!((1u32 << 23).saturating_mul(1 << 23), u32::MAX);
|
||||
/// ```
|
||||
#[unstable(feature = "wrapping", issue = "27755")]
|
||||
#[inline]
|
||||
pub fn saturating_mul(self, other: Self) -> Self {
|
||||
self.checked_mul(other).unwrap_or(Self::max_value())
|
||||
}
|
||||
|
||||
/// Wrapping (modular) addition. Computes `self + other`,
|
||||
/// wrapping around at the boundary of the type.
|
||||
///
|
||||
@ -1383,6 +1822,211 @@ pub fn wrapping_shr(self, rhs: u32) -> Self {
|
||||
self.overflowing_shr(rhs).0
|
||||
}
|
||||
|
||||
/// Calculates `self` + `rhs`
|
||||
///
|
||||
/// Returns a tuple of the addition 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(wrapping)]
|
||||
///
|
||||
/// use std::u32;
|
||||
///
|
||||
/// assert_eq!(5u32.overflowing_add(2), (7, false));
|
||||
/// assert_eq!(u32::MAX.overflowing_add(1), (0, true));
|
||||
/// ```
|
||||
#[inline]
|
||||
#[unstable(feature = "wrapping", issue = "27755")]
|
||||
pub fn overflowing_add(self, rhs: Self) -> (Self, bool) {
|
||||
unsafe {
|
||||
let (a, b) = $add_with_overflow(self as $ActualT,
|
||||
rhs as $ActualT);
|
||||
(a as Self, b)
|
||||
}
|
||||
}
|
||||
|
||||
/// Calculates `self` - `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(wrapping)]
|
||||
///
|
||||
/// use std::u32;
|
||||
///
|
||||
/// assert_eq!(5u32.overflowing_sub(2), (3, false));
|
||||
/// assert_eq!(0u32.overflowing_sub(1), (u32::MAX, true));
|
||||
/// ```
|
||||
#[inline]
|
||||
#[unstable(feature = "wrapping", issue = "27755")]
|
||||
pub fn overflowing_sub(self, rhs: Self) -> (Self, bool) {
|
||||
unsafe {
|
||||
let (a, b) = $sub_with_overflow(self as $ActualT,
|
||||
rhs as $ActualT);
|
||||
(a as Self, b)
|
||||
}
|
||||
}
|
||||
|
||||
/// Calculates the multiplication of `self` and `rhs`.
|
||||
///
|
||||
/// Returns a tuple of the multiplication 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(wrapping)]
|
||||
///
|
||||
/// assert_eq!(5u32.overflowing_mul(2), (10, false));
|
||||
/// assert_eq!(1_000_000_000u32.overflowing_mul(10), (1410065408, true));
|
||||
/// ```
|
||||
#[inline]
|
||||
#[unstable(feature = "wrapping", issue = "27755")]
|
||||
pub fn overflowing_mul(self, rhs: Self) -> (Self, bool) {
|
||||
unsafe {
|
||||
let (a, b) = $mul_with_overflow(self as $ActualT,
|
||||
rhs as $ActualT);
|
||||
(a as Self, b)
|
||||
}
|
||||
}
|
||||
|
||||
/// Calculates the divisor when `self` is divided by `rhs`.
|
||||
///
|
||||
/// Returns a tuple of the divisor along with a boolean indicating
|
||||
/// whether an arithmetic overflow would occur. Note that for unsigned
|
||||
/// integers overflow never occurs, so the second value is always
|
||||
/// `false`.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function will panic if `rhs` is 0.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(wrapping)]
|
||||
///
|
||||
/// assert_eq!(5u32.overflowing_div(2), (2, false));
|
||||
/// ```
|
||||
#[inline]
|
||||
#[unstable(feature = "wrapping", issue = "27755")]
|
||||
pub fn overflowing_div(self, rhs: Self) -> (Self, bool) {
|
||||
(self / rhs, false)
|
||||
}
|
||||
|
||||
/// Calculates the remainder when `self` is divided by `rhs`.
|
||||
///
|
||||
/// Returns a tuple of the remainder after dividing along with a boolean
|
||||
/// indicating whether an arithmetic overflow would occur. Note that for
|
||||
/// unsigned integers overflow never occurs, so the second value is
|
||||
/// always `false`.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function will panic if `rhs` is 0.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(wrapping)]
|
||||
///
|
||||
/// assert_eq!(5u32.overflowing_rem(2), (1, false));
|
||||
/// ```
|
||||
#[inline]
|
||||
#[unstable(feature = "wrapping", issue = "27755")]
|
||||
pub fn overflowing_rem(self, rhs: Self) -> (Self, bool) {
|
||||
(self % rhs, false)
|
||||
}
|
||||
|
||||
/// Negates self in an overflowing fashion.
|
||||
///
|
||||
/// Returns `!self + 1` using wrapping operations to return the value
|
||||
/// that represents the negation of this unsigned value. Note that for
|
||||
/// positive unsigned values overflow always occurs, but negating 0 does
|
||||
/// not overflow.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(wrapping)]
|
||||
///
|
||||
/// assert_eq!(0u32.overflowing_neg(), (0, false));
|
||||
/// assert_eq!(2u32.overflowing_neg(), (-2i32 as u32, true));
|
||||
/// ```
|
||||
#[inline]
|
||||
#[unstable(feature = "wrapping", issue = "27755")]
|
||||
pub fn overflowing_neg(self) -> (Self, bool) {
|
||||
((!self).wrapping_add(1), self != 0)
|
||||
}
|
||||
|
||||
/// Shifts self left by `rhs` bits.
|
||||
///
|
||||
/// Returns a tuple of the shifted version of self along with a boolean
|
||||
/// indicating whether the shift value was larger than or equal to the
|
||||
/// number of bits. If the shift value is too large, then value is
|
||||
/// masked (N-1) where N is the number of bits, and this value is then
|
||||
/// used to perform the shift.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(wrapping)]
|
||||
///
|
||||
/// assert_eq!(0x10u32.overflowing_shl(4), (0x100, false));
|
||||
/// assert_eq!(0x10u32.overflowing_shl(36), (0x100, true));
|
||||
/// ```
|
||||
#[inline]
|
||||
#[unstable(feature = "wrapping", issue = "27755")]
|
||||
pub fn overflowing_shl(self, rhs: u32) -> (Self, bool) {
|
||||
(self << (rhs & ($BITS - 1)), (rhs > ($BITS - 1)))
|
||||
}
|
||||
|
||||
/// Shifts self right by `rhs` bits.
|
||||
///
|
||||
/// Returns a tuple of the shifted version of self along with a boolean
|
||||
/// indicating whether the shift value was larger than or equal to the
|
||||
/// number of bits. If the shift value is too large, then value is
|
||||
/// masked (N-1) where N is the number of bits, and this value is then
|
||||
/// used to perform the shift.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(wrapping)]
|
||||
///
|
||||
/// assert_eq!(0x10u32.overflowing_shr(4), (0x1, false));
|
||||
/// assert_eq!(0x10u32.overflowing_shr(36), (0x1, true));
|
||||
/// ```
|
||||
#[inline]
|
||||
#[unstable(feature = "wrapping", issue = "27755")]
|
||||
pub fn overflowing_shr(self, rhs: u32) -> (Self, bool) {
|
||||
(self >> (rhs & ($BITS - 1)), (rhs > ($BITS - 1)))
|
||||
}
|
||||
|
||||
/// Raises self to the power of `exp`, using exponentiation by squaring.
|
||||
///
|
||||
/// # Examples
|
||||
|
Loading…
Reference in New Issue
Block a user