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
|
// `Int` + `SignedInt` implemented for signed integers
|
||||||
macro_rules! int_impl {
|
macro_rules! int_impl {
|
||||||
($ActualT:ty, $UnsignedT:ty, $BITS:expr,
|
($ActualT:ident, $UnsignedT:ty, $BITS:expr,
|
||||||
$add_with_overflow:path,
|
$add_with_overflow:path,
|
||||||
$sub_with_overflow:path,
|
$sub_with_overflow:path,
|
||||||
$mul_with_overflow:path) => {
|
$mul_with_overflow:path) => {
|
||||||
@ -393,7 +393,8 @@ pub fn to_le(self) -> Self {
|
|||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn checked_add(self, other: Self) -> Option<Self> {
|
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
|
/// 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")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn checked_sub(self, other: Self) -> Option<Self> {
|
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
|
/// 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")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn checked_mul(self, other: Self) -> Option<Self> {
|
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`
|
/// 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")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn checked_div(self, other: Self) -> Option<Self> {
|
pub fn checked_div(self, other: Self) -> Option<Self> {
|
||||||
match other {
|
if other == 0 {
|
||||||
0 => None,
|
None
|
||||||
-1 if self == Self::min_value()
|
} else {
|
||||||
=> None,
|
let (a, b) = self.overflowing_div(other);
|
||||||
other => Some(self / 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
|
/// Saturating integer addition. Computes `self + other`, saturating at
|
||||||
/// the numeric bounds instead of overflowing.
|
/// the numeric bounds instead of overflowing.
|
||||||
///
|
///
|
||||||
@ -468,7 +560,7 @@ pub fn checked_div(self, other: Self) -> Option<Self> {
|
|||||||
#[inline]
|
#[inline]
|
||||||
pub fn saturating_add(self, other: Self) -> Self {
|
pub fn saturating_add(self, other: Self) -> Self {
|
||||||
match self.checked_add(other) {
|
match self.checked_add(other) {
|
||||||
Some(x) => x,
|
Some(x) => x,
|
||||||
None if other >= Self::zero() => Self::max_value(),
|
None if other >= Self::zero() => Self::max_value(),
|
||||||
None => Self::min_value(),
|
None => Self::min_value(),
|
||||||
}
|
}
|
||||||
@ -489,12 +581,40 @@ pub fn saturating_add(self, other: Self) -> Self {
|
|||||||
#[inline]
|
#[inline]
|
||||||
pub fn saturating_sub(self, other: Self) -> Self {
|
pub fn saturating_sub(self, other: Self) -> Self {
|
||||||
match self.checked_sub(other) {
|
match self.checked_sub(other) {
|
||||||
Some(x) => x,
|
Some(x) => x,
|
||||||
None if other >= Self::zero() => Self::min_value(),
|
None if other >= Self::zero() => Self::min_value(),
|
||||||
None => Self::max_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 (modular) addition. Computes `self + other`,
|
||||||
/// wrapping around at the boundary of the type.
|
/// 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`
|
/// in the type. In such a case, this function returns `MIN`
|
||||||
/// itself.
|
/// itself.
|
||||||
///
|
///
|
||||||
|
/// # Panics
|
||||||
|
///
|
||||||
|
/// This function will panic if `rhs` is 0.
|
||||||
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// Basic usage:
|
/// Basic usage:
|
||||||
@ -584,6 +708,10 @@ pub fn wrapping_div(self, rhs: Self) -> Self {
|
|||||||
/// -1` on a signed type (where `MIN` is the negative
|
/// -1` on a signed type (where `MIN` is the negative
|
||||||
/// minimal value). In such a case, this function returns `0`.
|
/// minimal value). In such a case, this function returns `0`.
|
||||||
///
|
///
|
||||||
|
/// # Panics
|
||||||
|
///
|
||||||
|
/// This function will panic if `rhs` is 0.
|
||||||
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// Basic usage:
|
/// Basic usage:
|
||||||
@ -657,6 +785,230 @@ pub fn wrapping_shr(self, rhs: u32) -> Self {
|
|||||||
self.overflowing_shr(rhs).0
|
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.
|
/// Raises self to the power of `exp`, using exponentiation by squaring.
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
@ -1121,7 +1473,8 @@ pub fn to_le(self) -> Self {
|
|||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn checked_add(self, other: Self) -> Option<Self> {
|
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
|
/// 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")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn checked_sub(self, other: Self) -> Option<Self> {
|
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
|
/// 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")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn checked_mul(self, other: Self) -> Option<Self> {
|
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`
|
/// 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
|
/// Saturating integer addition. Computes `self + other`, saturating at
|
||||||
/// the numeric bounds instead of overflowing.
|
/// 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 (modular) addition. Computes `self + other`,
|
||||||
/// wrapping around at the boundary of the type.
|
/// 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
|
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.
|
/// Raises self to the power of `exp`, using exponentiation by squaring.
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
|
Loading…
Reference in New Issue
Block a user