#![stable(feature = "rust1", since = "1.0.0")]
-use convert::{Infallible, TryFrom};
+use convert::TryFrom;
use fmt;
use intrinsics;
+#[allow(deprecated)] use nonzero::NonZero;
use ops;
use str::FromStr;
+macro_rules! impl_nonzero_fmt {
+ ( #[$stability: meta] ( $( $Trait: ident ),+ ) for $Ty: ident ) => {
+ $(
+ #[$stability]
+ #[allow(deprecated)]
+ impl fmt::$Trait for $Ty {
+ #[inline]
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ self.get().fmt(f)
+ }
+ }
+ )+
+ }
+}
+
+macro_rules! nonzero_integers {
+ ( #[$stability: meta] #[$deprecation: meta] $( $Ty: ident($Int: ty); )+ ) => {
+ $(
+ /// An integer that is known not to equal zero.
+ ///
+ /// This may enable some memory layout optimization such as:
+ ///
+ /// ```rust
+ /// # #![feature(nonzero)]
+ /// use std::mem::size_of;
+ /// assert_eq!(size_of::<Option<std::num::NonZeroU32>>(), size_of::<u32>());
+ /// ```
+ #[$stability]
+ #[$deprecation]
+ #[allow(deprecated)]
+ #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
+ pub struct $Ty(NonZero<$Int>);
+
+ #[allow(deprecated)]
+ impl $Ty {
+ /// Create a non-zero without checking the value.
+ ///
+ /// # Safety
+ ///
+ /// The value must not be zero.
+ #[$stability]
+ #[inline]
+ pub const unsafe fn new_unchecked(n: $Int) -> Self {
+ $Ty(NonZero(n))
+ }
+
+ /// Create a non-zero if the given value is not zero.
+ #[$stability]
+ #[inline]
+ pub fn new(n: $Int) -> Option<Self> {
+ if n != 0 {
+ Some($Ty(NonZero(n)))
+ } else {
+ None
+ }
+ }
+
+ /// Returns the value as a primitive type.
+ #[$stability]
+ #[inline]
+ pub fn get(self) -> $Int {
+ self.0 .0
+ }
+
+ }
+
+ impl_nonzero_fmt! {
+ #[$stability]
+ (Debug, Display, Binary, Octal, LowerHex, UpperHex) for $Ty
+ }
+ )+
+ }
+}
+
+nonzero_integers! {
+ #[unstable(feature = "nonzero", issue = "49137")]
+ #[allow(deprecated)] // Redundant, works around "error: inconsistent lockstep iteration"
+ NonZeroU8(u8);
+ NonZeroU16(u16);
+ NonZeroU32(u32);
+ NonZeroU64(u64);
+ NonZeroU128(u128);
+ NonZeroUsize(usize);
+}
+
+nonzero_integers! {
+ #[unstable(feature = "nonzero", issue = "49137")]
+ #[rustc_deprecated(since = "1.26.0", reason = "\
+ signed non-zero integers are considered for removal due to lack of known use cases. \
+ If you’re using them, please comment on https://github.com/rust-lang/rust/issues/49137")]
+ NonZeroI8(i8);
+ NonZeroI16(i16);
+ NonZeroI32(i32);
+ NonZeroI64(i64);
+ NonZeroI128(i128);
+ NonZeroIsize(isize);
+}
+
/// Provides intentionally-wrapped arithmetic on `T`.
///
/// Operations like `+` on `u32` values is intended to never overflow,
pub mod bignum;
pub mod diy_float;
+macro_rules! doc_comment {
+ ($x:expr, $($tt:tt)*) => {
+ #[doc = $x]
+ $($tt)*
+ };
+}
+
// `Int` + `SignedInt` implemented for signed integers
macro_rules! int_impl {
- ($SelfT:ty, $ActualT:ident, $UnsignedT:ty, $BITS:expr) => {
- /// Returns the smallest value that can be represented by this integer type.
- ///
- /// # Examples
- ///
- /// Basic usage:
- ///
- /// ```
- /// assert_eq!(i8::min_value(), -128);
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline]
- pub const fn min_value() -> Self {
- !0 ^ ((!0 as $UnsignedT) >> 1) as Self
+ ($SelfT:ty, $ActualT:ident, $UnsignedT:ty, $BITS:expr, $Min:expr, $Max:expr, $Feature:expr,
+ $EndFeature:expr) => {
+ doc_comment! {
+ concat!("Returns the smallest value that can be represented by this integer type.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "assert_eq!(", stringify!($SelfT), "::min_value(), ", stringify!($Min), ");",
+$EndFeature, "
+```"),
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
+ pub const fn min_value() -> Self {
+ !0 ^ ((!0 as $UnsignedT) >> 1) as Self
+ }
}
- /// Returns the largest value that can be represented by this integer type.
- ///
- /// # Examples
- ///
- /// Basic usage:
- ///
- /// ```
- /// assert_eq!(i8::max_value(), 127);
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline]
- pub const fn max_value() -> Self {
- !Self::min_value()
+ doc_comment! {
+ concat!("Returns the largest value that can be represented by this integer type.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "assert_eq!(", stringify!($SelfT), "::max_value(), ", stringify!($Max), ");",
+$EndFeature, "
+```"),
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
+ pub const fn max_value() -> Self {
+ !Self::min_value()
+ }
}
- /// Converts a string slice in a given base to an integer.
- ///
- /// The string is expected to be an optional `+` or `-` sign
- /// followed by digits.
- /// Leading and trailing whitespace represent an error.
- /// Digits are a subset of these characters, depending on `radix`:
- ///
- /// * `0-9`
- /// * `a-z`
- /// * `A-Z`
- ///
- /// # Panics
- ///
- /// This function panics if `radix` is not in the range from 2 to 36.
- ///
- /// # Examples
- ///
- /// Basic usage:
- ///
- /// ```
- /// assert_eq!(i32::from_str_radix("A", 16), Ok(10));
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- pub fn from_str_radix(src: &str, radix: u32) -> Result<Self, ParseIntError> {
- from_str_radix(src, radix)
+ doc_comment! {
+ concat!("Converts a string slice in a given base to an integer.
+
+The string is expected to be an optional `+` or `-` sign followed by digits.
+Leading and trailing whitespace represent an error. Digits are a subset of these characters,
+depending on `radix`:
+
+ * `0-9`
+ * `a-z`
+ * `a-z`
+
+# Panics
+
+This function panics if `radix` is not in the range from 2 to 36.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "assert_eq!(", stringify!($SelfT), "::from_str_radix(\"A\", 16), Ok(10));",
+$EndFeature, "
+```"),
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub fn from_str_radix(src: &str, radix: u32) -> Result<Self, ParseIntError> {
+ from_str_radix(src, radix)
+ }
}
- /// Returns the number of ones in the binary representation of `self`.
- ///
- /// # Examples
- ///
- /// Basic usage:
- ///
- /// ```
- /// let n = -0b1000_0000i8;
- ///
- /// assert_eq!(n.count_ones(), 1);
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline]
- pub fn count_ones(self) -> u32 { (self as $UnsignedT).count_ones() }
+ doc_comment! {
+ concat!("Returns the number of ones in the binary representation of `self`.
- /// Returns the number of zeros in the binary representation of `self`.
- ///
- /// # Examples
- ///
- /// Basic usage:
- ///
- /// ```
- /// let n = -0b1000_0000i8;
- ///
- /// assert_eq!(n.count_zeros(), 7);
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline]
- pub fn count_zeros(self) -> u32 {
- (!self).count_ones()
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "let n = 0b100_0000", stringify!($SelfT), ";
+
+assert_eq!(n.count_ones(), 1);",
+$EndFeature, "
+```
+"),
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
+ pub fn count_ones(self) -> u32 { (self as $UnsignedT).count_ones() }
}
- /// Returns the number of leading zeros in the binary representation
- /// of `self`.
- ///
- /// # Examples
- ///
- /// Basic usage:
- ///
- /// ```
- /// let n = -1i16;
- ///
- /// assert_eq!(n.leading_zeros(), 0);
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline]
- pub fn leading_zeros(self) -> u32 {
- (self as $UnsignedT).leading_zeros()
+ doc_comment! {
+ concat!("Returns the number of zeros in the binary representation of `self`.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "assert_eq!(", stringify!($SelfT), "::max_value().count_zeros(), 1);", $EndFeature, "
+```"),
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
+ pub fn count_zeros(self) -> u32 {
+ (!self).count_ones()
+ }
}
- /// Returns the number of trailing zeros in the binary representation
- /// of `self`.
- ///
- /// # Examples
- ///
- /// Basic usage:
- ///
- /// ```
- /// let n = -4i8;
- ///
- /// assert_eq!(n.trailing_zeros(), 2);
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline]
- pub fn trailing_zeros(self) -> u32 {
- (self as $UnsignedT).trailing_zeros()
+ doc_comment! {
+ concat!("Returns the number of leading zeros in the binary representation of `self`.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "let n = -1", stringify!($SelfT), ";
+
+assert_eq!(n.leading_zeros(), 0);",
+$EndFeature, "
+```"),
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
+ pub fn leading_zeros(self) -> u32 {
+ (self as $UnsignedT).leading_zeros()
+ }
+ }
+
+ doc_comment! {
+ concat!("Returns the number of trailing zeros in the binary representation of `self`.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "let n = -4", stringify!($SelfT), ";
+
+assert_eq!(n.trailing_zeros(), 2);",
+$EndFeature, "
+```"),
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
+ pub fn trailing_zeros(self) -> u32 {
+ (self as $UnsignedT).trailing_zeros()
+ }
}
/// Shifts the bits to the left by a specified amount, `n`,
///
/// # Examples
///
+ /// Please note that this example is shared between integer types.
+ /// Which explains why `i64` is used here.
+ ///
/// Basic usage:
///
/// ```
///
/// # Examples
///
+ /// Please note that this example is shared between integer types.
+ /// Which explains why `i64` is used here.
+ ///
/// Basic usage:
///
/// ```
///
/// # Examples
///
+ /// Please note that this example is shared between integer types.
+ /// Which explains why `i16` is used here.
+ ///
/// Basic usage:
///
/// ```
(self as $UnsignedT).swap_bytes() as Self
}
- /// Converts an integer from big endian to the target's endianness.
- ///
- /// On big endian this is a no-op. On little endian the bytes are
- /// swapped.
+ /// Reverses the bit pattern of the integer.
///
/// # Examples
///
- /// Basic usage:
- ///
- /// ```
- /// let n = 0x0123456789ABCDEFi64;
- ///
- /// if cfg!(target_endian = "big") {
- /// assert_eq!(i64::from_be(n), n)
- /// } else {
- /// assert_eq!(i64::from_be(n), n.swap_bytes())
- /// }
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline]
- pub fn from_be(x: Self) -> Self {
- if cfg!(target_endian = "big") { x } else { x.swap_bytes() }
- }
-
- /// Converts an integer from little endian to the target's endianness.
- ///
- /// On little endian this is a no-op. On big endian the bytes are
- /// swapped.
- ///
- /// # Examples
+ /// Please note that this example is shared between integer types.
+ /// Which explains why `i16` is used here.
///
/// Basic usage:
///
/// ```
- /// let n = 0x0123456789ABCDEFi64;
- ///
- /// if cfg!(target_endian = "little") {
- /// assert_eq!(i64::from_le(n), n)
- /// } else {
- /// assert_eq!(i64::from_le(n), n.swap_bytes())
- /// }
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline]
- pub fn from_le(x: Self) -> Self {
- if cfg!(target_endian = "little") { x } else { x.swap_bytes() }
- }
-
- /// Converts `self` to big endian from the target's endianness.
- ///
- /// On big endian this is a no-op. On little endian the bytes are
- /// swapped.
+ /// #![feature(reverse_bits)]
///
- /// # Examples
- ///
- /// Basic usage:
+ /// let n: i16 = 0b0000000_01010101;
+ /// assert_eq!(n, 85);
///
- /// ```
- /// let n = 0x0123456789ABCDEFi64;
+ /// let m = n.reverse_bits();
///
- /// if cfg!(target_endian = "big") {
- /// assert_eq!(n.to_be(), n)
- /// } else {
- /// assert_eq!(n.to_be(), n.swap_bytes())
- /// }
+ /// assert_eq!(m as u16, 0b10101010_00000000);
+ /// assert_eq!(m, -22016);
/// ```
- #[stable(feature = "rust1", since = "1.0.0")]
+ #[unstable(feature = "reverse_bits", issue = "48763")]
+ #[cfg(not(stage0))]
#[inline]
- pub fn to_be(self) -> Self { // or not to be?
- if cfg!(target_endian = "big") { self } else { self.swap_bytes() }
+ pub fn reverse_bits(self) -> Self {
+ (self as $UnsignedT).reverse_bits() as Self
}
- /// Converts `self` to little endian from the target's endianness.
- ///
- /// On little endian this is a no-op. On big endian the bytes are
- /// swapped.
- ///
- /// # Examples
- ///
- /// Basic usage:
- ///
- /// ```
- /// let n = 0x0123456789ABCDEFi64;
- ///
- /// if cfg!(target_endian = "little") {
- /// assert_eq!(n.to_le(), n)
- /// } else {
- /// assert_eq!(n.to_le(), n.swap_bytes())
- /// }
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline]
- pub fn to_le(self) -> Self {
- if cfg!(target_endian = "little") { self } else { self.swap_bytes() }
- }
+ doc_comment! {
+ concat!("Converts an integer from big endian to the target's endianness.
- /// Checked integer addition. Computes `self + rhs`, returning `None`
- /// if overflow occurred.
- ///
- /// # Examples
- ///
- /// Basic usage:
- ///
- /// ```
- /// assert_eq!(7i16.checked_add(32760), Some(32767));
- /// assert_eq!(8i16.checked_add(32760), None);
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline]
- pub fn checked_add(self, rhs: Self) -> Option<Self> {
- let (a, b) = self.overflowing_add(rhs);
- if b {None} else {Some(a)}
- }
+On big endian this is a no-op. On little endian the bytes are swapped.
- /// Checked integer subtraction. Computes `self - rhs`, returning
- /// `None` if overflow occurred.
- ///
- /// # Examples
- ///
- /// Basic usage:
- ///
- /// ```
- /// assert_eq!((-127i8).checked_sub(1), Some(-128));
- /// assert_eq!((-128i8).checked_sub(1), None);
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline]
- pub fn checked_sub(self, rhs: Self) -> Option<Self> {
- let (a, b) = self.overflowing_sub(rhs);
- if b {None} else {Some(a)}
- }
+# Examples
- /// Checked integer multiplication. Computes `self * rhs`, returning
- /// `None` if overflow occurred.
- ///
- /// # Examples
- ///
- /// Basic usage:
- ///
- /// ```
- /// assert_eq!(6i8.checked_mul(21), Some(126));
- /// assert_eq!(6i8.checked_mul(22), None);
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline]
- pub fn checked_mul(self, rhs: Self) -> Option<Self> {
- let (a, b) = self.overflowing_mul(rhs);
- if b {None} else {Some(a)}
- }
+Basic usage:
- /// Checked integer division. Computes `self / rhs`, returning `None`
- /// if `rhs == 0` or the division results in overflow.
- ///
- /// # Examples
- ///
- /// Basic usage:
- ///
- /// ```
- /// assert_eq!((-127i8).checked_div(-1), Some(127));
- /// assert_eq!((-128i8).checked_div(-1), None);
- /// assert_eq!((1i8).checked_div(0), None);
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline]
- pub fn checked_div(self, rhs: Self) -> Option<Self> {
- if rhs == 0 || (self == Self::min_value() && rhs == -1) {
- None
- } else {
- Some(unsafe { intrinsics::unchecked_div(self, rhs) })
+```
+", $Feature, "let n = 0x1A", stringify!($SelfT), ";
+
+if cfg!(target_endian = \"big\") {
+ assert_eq!(", stringify!($SelfT), "::from_be(n), n)
+} else {
+ assert_eq!(", stringify!($SelfT), "::from_be(n), n.swap_bytes())
+}",
+$EndFeature, "
+```"),
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
+ pub fn from_be(x: Self) -> Self {
+ if cfg!(target_endian = "big") { x } else { x.swap_bytes() }
}
}
- /// Checked integer remainder. Computes `self % rhs`, returning `None`
- /// if `rhs == 0` or the division results in overflow.
- ///
- /// # Examples
- ///
- /// Basic usage:
- ///
- /// ```
- /// 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);
- /// ```
- #[stable(feature = "wrapping", since = "1.7.0")]
- #[inline]
- pub fn checked_rem(self, rhs: Self) -> Option<Self> {
- if rhs == 0 || (self == Self::min_value() && rhs == -1) {
- None
- } else {
- Some(unsafe { intrinsics::unchecked_rem(self, rhs) })
+ doc_comment! {
+ concat!("Converts an integer from little endian to the target's endianness.
+
+On little endian this is a no-op. On big endian the bytes are swapped.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "let n = 0x1A", stringify!($SelfT), ";
+
+if cfg!(target_endian = \"little\") {
+ assert_eq!(", stringify!($SelfT), "::from_le(n), n)
+} else {
+ assert_eq!(", stringify!($SelfT), "::from_le(n), n.swap_bytes())
+}",
+$EndFeature, "
+```"),
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
+ pub fn from_le(x: Self) -> Self {
+ if cfg!(target_endian = "little") { x } else { x.swap_bytes() }
}
}
- /// Checked negation. Computes `-self`, returning `None` if `self ==
- /// MIN`.
- ///
- /// # Examples
- ///
- /// Basic usage:
- ///
- /// ```
- /// use std::i32;
- ///
- /// assert_eq!(5i32.checked_neg(), Some(-5));
- /// assert_eq!(i32::MIN.checked_neg(), None);
- /// ```
- #[stable(feature = "wrapping", since = "1.7.0")]
- #[inline]
- pub fn checked_neg(self) -> Option<Self> {
- let (a, b) = self.overflowing_neg();
- if b {None} else {Some(a)}
+ doc_comment! {
+ concat!("Converts `self` to big endian from the target's endianness.
+
+On big endian this is a no-op. On little endian the bytes are swapped.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "let n = 0x1A", stringify!($SelfT), ";
+
+if cfg!(target_endian = \"big\") {
+ assert_eq!(n.to_be(), n)
+} else {
+ assert_eq!(n.to_be(), n.swap_bytes())
+}",
+$EndFeature, "
+```"),
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
+ pub fn to_be(self) -> Self { // or not to be?
+ if cfg!(target_endian = "big") { self } else { self.swap_bytes() }
+ }
}
- /// 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:
- ///
- /// ```
- /// assert_eq!(0x10i32.checked_shl(4), Some(0x100));
- /// assert_eq!(0x10i32.checked_shl(33), None);
- /// ```
- #[stable(feature = "wrapping", since = "1.7.0")]
- #[inline]
- pub fn checked_shl(self, rhs: u32) -> Option<Self> {
- let (a, b) = self.overflowing_shl(rhs);
- if b {None} else {Some(a)}
+ doc_comment! {
+ concat!("Converts `self` to little endian from the target's endianness.
+
+On little endian this is a no-op. On big endian the bytes are swapped.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "let n = 0x1A", stringify!($SelfT), ";
+
+if cfg!(target_endian = \"little\") {
+ assert_eq!(n.to_le(), n)
+} else {
+ assert_eq!(n.to_le(), n.swap_bytes())
+}",
+$EndFeature, "
+```"),
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
+ pub fn to_le(self) -> Self {
+ if cfg!(target_endian = "little") { self } else { self.swap_bytes() }
+ }
}
- /// 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:
- ///
- /// ```
- /// assert_eq!(0x10i32.checked_shr(4), Some(0x1));
- /// assert_eq!(0x10i32.checked_shr(33), None);
- /// ```
- #[stable(feature = "wrapping", since = "1.7.0")]
- #[inline]
- pub fn checked_shr(self, rhs: u32) -> Option<Self> {
- let (a, b) = self.overflowing_shr(rhs);
- if b {None} else {Some(a)}
+ doc_comment! {
+ concat!("Checked integer addition. Computes `self + rhs`, returning `None`
+if overflow occurred.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "assert_eq!((", stringify!($SelfT),
+"::max_value() - 2).checked_add(1), Some(", stringify!($SelfT), "::max_value() - 1));
+assert_eq!((", stringify!($SelfT), "::max_value() - 2).checked_add(3), None);",
+$EndFeature, "
+```"),
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
+ pub fn checked_add(self, rhs: Self) -> Option<Self> {
+ let (a, b) = self.overflowing_add(rhs);
+ if b {None} else {Some(a)}
+ }
}
- /// Checked absolute value. Computes `self.abs()`, returning `None` if
- /// `self == MIN`.
- ///
- /// # Examples
- ///
- /// Basic usage:
- ///
- /// ```
- /// use std::i32;
- ///
- /// assert_eq!((-5i32).checked_abs(), Some(5));
- /// assert_eq!(i32::MIN.checked_abs(), None);
- /// ```
- #[stable(feature = "no_panic_abs", since = "1.13.0")]
- #[inline]
- pub fn checked_abs(self) -> Option<Self> {
- if self.is_negative() {
- self.checked_neg()
- } else {
- Some(self)
+ doc_comment! {
+ concat!("Checked integer subtraction. Computes `self - rhs`, returning `None` if
+overflow occurred.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "assert_eq!((", stringify!($SelfT),
+"::min_value() + 2).checked_sub(1), Some(", stringify!($SelfT), "::min_value() + 1));
+assert_eq!((", stringify!($SelfT), "::min_value() + 2).checked_sub(3), None);",
+$EndFeature, "
+```"),
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
+ pub fn checked_sub(self, rhs: Self) -> Option<Self> {
+ let (a, b) = self.overflowing_sub(rhs);
+ if b {None} else {Some(a)}
}
}
- /// Saturating integer addition. Computes `self + rhs`, saturating at
- /// the numeric bounds instead of overflowing.
- ///
- /// # Examples
- ///
- /// Basic usage:
- ///
- /// ```
- /// assert_eq!(100i8.saturating_add(1), 101);
- /// assert_eq!(100i8.saturating_add(127), 127);
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline]
- pub fn saturating_add(self, rhs: Self) -> Self {
- match self.checked_add(rhs) {
- Some(x) => x,
- None if rhs >= 0 => Self::max_value(),
- None => Self::min_value(),
+ doc_comment! {
+ concat!("Checked integer multiplication. Computes `self * rhs`, returning `None` if
+overflow occurred.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "assert_eq!(", stringify!($SelfT),
+"::max_value().checked_mul(1), Some(", stringify!($SelfT), "::max_value()));
+assert_eq!(", stringify!($SelfT), "::max_value().checked_mul(2), None);",
+$EndFeature, "
+```"),
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
+ pub fn checked_mul(self, rhs: Self) -> Option<Self> {
+ let (a, b) = self.overflowing_mul(rhs);
+ if b {None} else {Some(a)}
}
}
- /// Saturating integer subtraction. Computes `self - rhs`, saturating
- /// at the numeric bounds instead of overflowing.
- ///
- /// # Examples
- ///
- /// Basic usage:
- ///
- /// ```
- /// assert_eq!(100i8.saturating_sub(127), -27);
- /// assert_eq!((-100i8).saturating_sub(127), -128);
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline]
- pub fn saturating_sub(self, rhs: Self) -> Self {
- match self.checked_sub(rhs) {
- Some(x) => x,
- None if rhs >= 0 => Self::min_value(),
- None => Self::max_value(),
+ doc_comment! {
+ concat!("Checked integer division. Computes `self / rhs`, returning `None` if `rhs == 0`
+or the division results in overflow.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "assert_eq!((", stringify!($SelfT),
+"::min_value() + 1).checked_div(-1), Some(", stringify!($Max), "));
+assert_eq!(", stringify!($SelfT), "::min_value().checked_div(-1), None);
+assert_eq!((1", stringify!($SelfT), ").checked_div(0), None);",
+$EndFeature, "
+```"),
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
+ pub fn checked_div(self, rhs: Self) -> Option<Self> {
+ if rhs == 0 || (self == Self::min_value() && rhs == -1) {
+ None
+ } else {
+ Some(unsafe { intrinsics::unchecked_div(self, rhs) })
+ }
}
}
- /// Saturating integer multiplication. Computes `self * rhs`,
- /// saturating at the numeric bounds instead of overflowing.
- ///
- /// # Examples
- ///
- /// Basic usage:
- ///
- /// ```
- /// 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);
- /// ```
- #[stable(feature = "wrapping", since = "1.7.0")]
- #[inline]
- pub fn saturating_mul(self, rhs: Self) -> Self {
- self.checked_mul(rhs).unwrap_or_else(|| {
- if (self < 0 && rhs < 0) || (self > 0 && rhs > 0) {
- Self::max_value()
+ doc_comment! {
+ concat!("Checked integer remainder. Computes `self % rhs`, returning `None` if
+`rhs == 0` or the division results in overflow.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "use std::", stringify!($SelfT), ";
+
+assert_eq!(5", stringify!($SelfT), ".checked_rem(2), Some(1));
+assert_eq!(5", stringify!($SelfT), ".checked_rem(0), None);
+assert_eq!(", stringify!($SelfT), "::MIN.checked_rem(-1), None);",
+$EndFeature, "
+```"),
+ #[stable(feature = "wrapping", since = "1.7.0")]
+ #[inline]
+ pub fn checked_rem(self, rhs: Self) -> Option<Self> {
+ if rhs == 0 || (self == Self::min_value() && rhs == -1) {
+ None
} else {
- Self::min_value()
+ Some(unsafe { intrinsics::unchecked_rem(self, rhs) })
}
- })
+ }
}
- /// Wrapping (modular) addition. Computes `self + rhs`,
- /// wrapping around at the boundary of the type.
- ///
- /// # Examples
- ///
- /// Basic usage:
- ///
- /// ```
- /// assert_eq!(100i8.wrapping_add(27), 127);
- /// assert_eq!(100i8.wrapping_add(127), -29);
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline]
- pub fn wrapping_add(self, rhs: Self) -> Self {
- unsafe {
- intrinsics::overflowing_add(self, rhs)
+ doc_comment! {
+ concat!("Checked negation. Computes `-self`, returning `None` if `self == MIN`.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "use std::", stringify!($SelfT), ";
+
+assert_eq!(5", stringify!($SelfT), ".checked_neg(), Some(-5));
+assert_eq!(", stringify!($SelfT), "::MIN.checked_neg(), None);",
+$EndFeature, "
+```"),
+ #[stable(feature = "wrapping", since = "1.7.0")]
+ #[inline]
+ pub fn checked_neg(self) -> Option<Self> {
+ let (a, b) = self.overflowing_neg();
+ if b {None} else {Some(a)}
}
}
- /// Wrapping (modular) subtraction. Computes `self - rhs`,
- /// wrapping around at the boundary of the type.
- ///
- /// # Examples
- ///
- /// Basic usage:
- ///
- /// ```
- /// assert_eq!(0i8.wrapping_sub(127), -127);
- /// assert_eq!((-2i8).wrapping_sub(127), 127);
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline]
- pub fn wrapping_sub(self, rhs: Self) -> Self {
- unsafe {
- intrinsics::overflowing_sub(self, rhs)
+ doc_comment! {
+ concat!("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, "assert_eq!(0x1", stringify!($SelfT), ".checked_shl(4), Some(0x10));
+assert_eq!(0x1", stringify!($SelfT), ".checked_shl(129), None);",
+$EndFeature, "
+```"),
+ #[stable(feature = "wrapping", since = "1.7.0")]
+ #[inline]
+ pub fn checked_shl(self, rhs: u32) -> Option<Self> {
+ let (a, b) = self.overflowing_shl(rhs);
+ if b {None} else {Some(a)}
}
}
- /// Wrapping (modular) multiplication. Computes `self *
- /// rhs`, wrapping around at the boundary of the type.
- ///
- /// # Examples
- ///
- /// Basic usage:
- ///
- /// ```
- /// assert_eq!(10i8.wrapping_mul(12), 120);
- /// assert_eq!(11i8.wrapping_mul(12), -124);
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline]
- pub fn wrapping_mul(self, rhs: Self) -> Self {
- unsafe {
- intrinsics::overflowing_mul(self, rhs)
+ doc_comment! {
+ concat!("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, "assert_eq!(0x10", stringify!($SelfT), ".checked_shr(4), Some(0x1));
+assert_eq!(0x10", stringify!($SelfT), ".checked_shr(128), None);",
+$EndFeature, "
+```"),
+ #[stable(feature = "wrapping", since = "1.7.0")]
+ #[inline]
+ pub fn checked_shr(self, rhs: u32) -> Option<Self> {
+ let (a, b) = self.overflowing_shr(rhs);
+ if b {None} else {Some(a)}
}
}
- /// Wrapping (modular) division. Computes `self / rhs`,
- /// wrapping around at the boundary of the type.
- ///
- /// The only case where such wrapping can occur is when one
- /// divides `MIN / -1` on a signed type (where `MIN` is the
- /// negative minimal value for the type); this is equivalent
- /// to `-MIN`, a positive value that is too large to represent
- /// in the type. In such a case, this function returns `MIN`
- /// itself.
- ///
- /// # Panics
- ///
- /// This function will panic if `rhs` is 0.
- ///
- /// # Examples
- ///
- /// Basic usage:
- ///
- /// ```
- /// assert_eq!(100u8.wrapping_div(10), 10);
- /// assert_eq!((-128i8).wrapping_div(-1), -128);
- /// ```
- #[stable(feature = "num_wrapping", since = "1.2.0")]
- #[inline]
- pub fn wrapping_div(self, rhs: Self) -> Self {
- self.overflowing_div(rhs).0
+ doc_comment! {
+ concat!("Checked absolute value. Computes `self.abs()`, returning `None` if
+`self == MIN`.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "use std::", stringify!($SelfT), ";
+
+assert_eq!((-5", stringify!($SelfT), ").checked_abs(), Some(5));
+assert_eq!(", stringify!($SelfT), "::MIN.checked_abs(), None);",
+$EndFeature, "
+```"),
+ #[stable(feature = "no_panic_abs", since = "1.13.0")]
+ #[inline]
+ pub fn checked_abs(self) -> Option<Self> {
+ if self.is_negative() {
+ self.checked_neg()
+ } else {
+ Some(self)
+ }
+ }
}
- /// Wrapping (modular) remainder. Computes `self % rhs`,
- /// wrapping around at the boundary of the type.
- ///
- /// Such wrap-around never actually occurs mathematically;
- /// implementation artifacts make `x % y` invalid for `MIN /
- /// -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:
- ///
- /// ```
- /// assert_eq!(100i8.wrapping_rem(10), 0);
- /// assert_eq!((-128i8).wrapping_rem(-1), 0);
- /// ```
- #[stable(feature = "num_wrapping", since = "1.2.0")]
- #[inline]
- pub fn wrapping_rem(self, rhs: Self) -> Self {
- self.overflowing_rem(rhs).0
+ doc_comment! {
+ concat!("Checked exponentiation. Computes `self.pow(exp)`, returning `None` if
+overflow occurred.
+
+# Examples
+
+Basic usage:
+
+```
+#![feature(no_panic_pow)]
+", $Feature, "assert_eq!(8", stringify!($SelfT), ".checked_pow(2), Some(64));
+assert_eq!(", stringify!($SelfT), "::max_value().checked_pow(2), None);",
+$EndFeature, "
+```"),
+
+ #[unstable(feature = "no_panic_pow", issue = "48320")]
+ #[inline]
+ pub fn checked_pow(self, mut exp: u32) -> Option<Self> {
+ let mut base = self;
+ let mut acc: Self = 1;
+
+ while exp > 1 {
+ if (exp & 1) == 1 {
+ acc = acc.checked_mul(base)?;
+ }
+ exp /= 2;
+ base = base.checked_mul(base)?;
+ }
+
+ // Deal with the final bit of the exponent separately, since
+ // squaring the base afterwards is not necessary and may cause a
+ // needless overflow.
+ if exp == 1 {
+ acc = acc.checked_mul(base)?;
+ }
+
+ Some(acc)
+ }
}
- /// Wrapping (modular) negation. Computes `-self`,
- /// wrapping around at the boundary of the type.
- ///
- /// The only case where such wrapping can occur is when one
- /// negates `MIN` on a signed type (where `MIN` is the
- /// negative minimal value for the type); this is a positive
- /// value that is too large to represent in the type. In such
- /// a case, this function returns `MIN` itself.
- ///
- /// # Examples
- ///
- /// Basic usage:
- ///
- /// ```
- /// assert_eq!(100i8.wrapping_neg(), -100);
- /// assert_eq!((-128i8).wrapping_neg(), -128);
- /// ```
- #[stable(feature = "num_wrapping", since = "1.2.0")]
- #[inline]
- pub fn wrapping_neg(self) -> Self {
- self.overflowing_neg().0
+ doc_comment! {
+ concat!("Saturating integer addition. Computes `self + rhs`, saturating at the numeric
+bounds instead of overflowing.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "assert_eq!(100", stringify!($SelfT), ".saturating_add(1), 101);
+assert_eq!(", stringify!($SelfT), "::max_value().saturating_add(100), ", stringify!($SelfT),
+"::max_value());",
+$EndFeature, "
+```"),
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
+ pub fn saturating_add(self, rhs: Self) -> Self {
+ match self.checked_add(rhs) {
+ Some(x) => x,
+ None if rhs >= 0 => Self::max_value(),
+ None => Self::min_value(),
+ }
+ }
}
- /// Panic-free bitwise shift-left; yields `self << mask(rhs)`,
- /// where `mask` removes any high-order bits of `rhs` that
- /// would cause the shift to exceed the bitwidth of the type.
- ///
- /// Note that this is *not* the same as a rotate-left; the
- /// RHS of a wrapping shift-left is restricted to the range
- /// of the type, rather than the bits shifted out of the LHS
- /// being returned to the other end. The primitive integer
- /// types all implement a `rotate_left` function, which may
- /// be what you want instead.
- ///
- /// # Examples
- ///
- /// Basic usage:
- ///
- /// ```
- /// assert_eq!((-1i8).wrapping_shl(7), -128);
- /// assert_eq!((-1i8).wrapping_shl(8), -1);
- /// ```
- #[stable(feature = "num_wrapping", since = "1.2.0")]
- #[inline]
- pub fn wrapping_shl(self, rhs: u32) -> Self {
- unsafe {
- intrinsics::unchecked_shl(self, (rhs & ($BITS - 1)) as $SelfT)
+ doc_comment! {
+ concat!("Saturating integer subtraction. Computes `self - rhs`, saturating at the
+numeric bounds instead of overflowing.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "assert_eq!(100", stringify!($SelfT), ".saturating_sub(127), -27);
+assert_eq!(", stringify!($SelfT), "::min_value().saturating_sub(100), ", stringify!($SelfT),
+"::min_value());",
+$EndFeature, "
+```"),
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
+ pub fn saturating_sub(self, rhs: Self) -> Self {
+ match self.checked_sub(rhs) {
+ Some(x) => x,
+ None if rhs >= 0 => Self::min_value(),
+ None => Self::max_value(),
+ }
}
}
- /// Panic-free bitwise shift-right; yields `self >> mask(rhs)`,
- /// where `mask` removes any high-order bits of `rhs` that
- /// would cause the shift to exceed the bitwidth of the type.
- ///
- /// Note that this is *not* the same as a rotate-right; the
- /// RHS of a wrapping shift-right is restricted to the range
- /// of the type, rather than the bits shifted out of the LHS
- /// being returned to the other end. The primitive integer
- /// types all implement a `rotate_right` function, which may
- /// be what you want instead.
- ///
- /// # Examples
- ///
- /// Basic usage:
- ///
- /// ```
- /// assert_eq!((-128i8).wrapping_shr(7), -1);
- /// assert_eq!((-128i8).wrapping_shr(8), -128);
- /// ```
- #[stable(feature = "num_wrapping", since = "1.2.0")]
- #[inline]
- pub fn wrapping_shr(self, rhs: u32) -> Self {
- unsafe {
- intrinsics::unchecked_shr(self, (rhs & ($BITS - 1)) as $SelfT)
+ doc_comment! {
+ concat!("Saturating integer multiplication. Computes `self * rhs`, saturating at the
+numeric bounds instead of overflowing.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "use std::", stringify!($SelfT), ";
+
+assert_eq!(10", stringify!($SelfT), ".saturating_mul(12), 120);
+assert_eq!(", stringify!($SelfT), "::MAX.saturating_mul(10), ", stringify!($SelfT), "::MAX);
+assert_eq!(", stringify!($SelfT), "::MIN.saturating_mul(10), ", stringify!($SelfT), "::MIN);",
+$EndFeature, "
+```"),
+ #[stable(feature = "wrapping", since = "1.7.0")]
+ #[inline]
+ pub fn saturating_mul(self, rhs: Self) -> Self {
+ self.checked_mul(rhs).unwrap_or_else(|| {
+ if (self < 0 && rhs < 0) || (self > 0 && rhs > 0) {
+ Self::max_value()
+ } else {
+ Self::min_value()
+ }
+ })
}
}
- /// Wrapping (modular) absolute value. Computes `self.abs()`,
- /// wrapping around at the boundary of the type.
- ///
- /// The only case where such wrapping can occur is when one takes
- /// the absolute value of the negative minimal value for the type
- /// this is a positive value that is too large to represent in the
- /// type. In such a case, this function returns `MIN` itself.
- ///
- /// # Examples
- ///
- /// Basic usage:
- ///
- /// ```
- /// assert_eq!(100i8.wrapping_abs(), 100);
- /// assert_eq!((-100i8).wrapping_abs(), 100);
- /// assert_eq!((-128i8).wrapping_abs(), -128);
- /// assert_eq!((-128i8).wrapping_abs() as u8, 128);
- /// ```
- #[stable(feature = "no_panic_abs", since = "1.13.0")]
- #[inline]
- pub fn wrapping_abs(self) -> Self {
- if self.is_negative() {
- self.wrapping_neg()
- } else {
- self
+ doc_comment! {
+ concat!("Saturating integer exponentiation. Computes `self.pow(exp)`,
+saturating at the numeric bounds instead of overflowing.
+
+# Examples
+
+Basic usage:
+
+```
+#![feature(no_panic_pow)]
+", $Feature, "use std::", stringify!($SelfT), ";
+
+assert_eq!((-4", stringify!($SelfT), ").saturating_pow(3), -64);
+assert_eq!(", stringify!($SelfT), "::MIN.saturating_pow(2), ", stringify!($SelfT), "::MAX);
+assert_eq!(", stringify!($SelfT), "::MIN.saturating_pow(3), ", stringify!($SelfT), "::MIN);",
+$EndFeature, "
+```"),
+ #[unstable(feature = "no_panic_pow", issue = "48320")]
+ #[inline]
+ pub fn saturating_pow(self, exp: u32) -> Self {
+ match self.checked_pow(exp) {
+ Some(x) => x,
+ None if self < 0 && exp % 2 == 1 => Self::min_value(),
+ None => Self::max_value(),
+ }
}
}
- /// 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
- ///
- /// ```
- /// use std::i32;
- ///
- /// assert_eq!(5i32.overflowing_add(2), (7, false));
- /// assert_eq!(i32::MAX.overflowing_add(1), (i32::MIN, true));
- /// ```
- #[inline]
- #[stable(feature = "wrapping", since = "1.7.0")]
- pub fn overflowing_add(self, rhs: Self) -> (Self, bool) {
- let (a, b) = unsafe {
- intrinsics::add_with_overflow(self as $ActualT,
- rhs as $ActualT)
- };
- (a as Self, b)
- }
+ doc_comment! {
+ concat!("Wrapping (modular) addition. Computes `self + rhs`, wrapping around at the
+boundary of the type.
- /// 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
- ///
- /// ```
- /// use std::i32;
- ///
- /// assert_eq!(5i32.overflowing_sub(2), (3, false));
- /// assert_eq!(i32::MIN.overflowing_sub(1), (i32::MAX, true));
- /// ```
- #[inline]
- #[stable(feature = "wrapping", since = "1.7.0")]
- pub fn overflowing_sub(self, rhs: Self) -> (Self, bool) {
- let (a, b) = unsafe {
- intrinsics::sub_with_overflow(self as $ActualT,
- rhs as $ActualT)
- };
- (a as Self, b)
- }
+# Examples
- /// 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
- ///
- /// ```
- /// assert_eq!(5i32.overflowing_mul(2), (10, false));
- /// assert_eq!(1_000_000_000i32.overflowing_mul(10), (1410065408, true));
- /// ```
- #[inline]
- #[stable(feature = "wrapping", since = "1.7.0")]
- pub fn overflowing_mul(self, rhs: Self) -> (Self, bool) {
- let (a, b) = unsafe {
- intrinsics::mul_with_overflow(self as $ActualT,
- rhs as $ActualT)
- };
- (a as Self, b)
- }
+Basic usage:
- /// 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
- ///
- /// ```
- /// use std::i32;
- ///
- /// assert_eq!(5i32.overflowing_div(2), (2, false));
- /// assert_eq!(i32::MIN.overflowing_div(-1), (i32::MIN, true));
- /// ```
- #[inline]
- #[stable(feature = "wrapping", since = "1.7.0")]
- pub fn overflowing_div(self, rhs: Self) -> (Self, bool) {
- if self == Self::min_value() && rhs == -1 {
- (self, true)
- } else {
- (self / rhs, false)
+```
+", $Feature, "assert_eq!(100", stringify!($SelfT), ".wrapping_add(27), 127);
+assert_eq!(", stringify!($SelfT), "::max_value().wrapping_add(2), ", stringify!($SelfT),
+"::min_value() + 1);",
+$EndFeature, "
+```"),
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
+ pub fn wrapping_add(self, rhs: Self) -> Self {
+ unsafe {
+ intrinsics::overflowing_add(self, rhs)
+ }
}
}
- /// 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
- ///
- /// ```
- /// use std::i32;
- ///
- /// assert_eq!(5i32.overflowing_rem(2), (1, false));
- /// assert_eq!(i32::MIN.overflowing_rem(-1), (0, true));
- /// ```
- #[inline]
- #[stable(feature = "wrapping", since = "1.7.0")]
- pub fn overflowing_rem(self, rhs: Self) -> (Self, bool) {
- if self == Self::min_value() && rhs == -1 {
- (0, true)
- } else {
- (self % rhs, false)
+ doc_comment! {
+ concat!("Wrapping (modular) subtraction. Computes `self - rhs`, wrapping around at the
+boundary of the type.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "assert_eq!(0", stringify!($SelfT), ".wrapping_sub(127), -127);
+assert_eq!((-2", stringify!($SelfT), ").wrapping_sub(", stringify!($SelfT), "::max_value()), ",
+stringify!($SelfT), "::max_value());",
+$EndFeature, "
+```"),
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
+ pub fn wrapping_sub(self, rhs: Self) -> Self {
+ unsafe {
+ intrinsics::overflowing_sub(self, rhs)
+ }
}
}
- /// 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
- ///
- /// ```
- /// use std::i32;
- ///
- /// assert_eq!(2i32.overflowing_neg(), (-2, false));
- /// assert_eq!(i32::MIN.overflowing_neg(), (i32::MIN, true));
- /// ```
- #[inline]
- #[stable(feature = "wrapping", since = "1.7.0")]
- pub fn overflowing_neg(self) -> (Self, bool) {
- if self == Self::min_value() {
- (Self::min_value(), true)
- } else {
- (-self, false)
+ doc_comment! {
+ concat!("Wrapping (modular) multiplication. Computes `self * rhs`, wrapping around at
+the boundary of the type.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "assert_eq!(10", stringify!($SelfT), ".wrapping_mul(12), 120);
+assert_eq!(11i8.wrapping_mul(12), -124);",
+$EndFeature, "
+```"),
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
+ pub fn wrapping_mul(self, rhs: Self) -> Self {
+ unsafe {
+ intrinsics::overflowing_mul(self, rhs)
+ }
}
}
- /// 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
- ///
- /// ```
- /// assert_eq!(0x10i32.overflowing_shl(4), (0x100, false));
- /// assert_eq!(0x10i32.overflowing_shl(36), (0x100, true));
- /// ```
- #[inline]
- #[stable(feature = "wrapping", since = "1.7.0")]
- pub fn overflowing_shl(self, rhs: u32) -> (Self, bool) {
- (self.wrapping_shl(rhs), (rhs > ($BITS - 1)))
+ doc_comment! {
+ concat!("Wrapping (modular) division. Computes `self / rhs`, wrapping around at the
+boundary of the type.
+
+The only case where such wrapping can occur is when one divides `MIN / -1` on a signed type (where
+`MIN` is the negative minimal value for the type); this is equivalent to `-MIN`, a positive value
+that is too large to represent in the type. In such a case, this function returns `MIN` itself.
+
+# Panics
+
+This function will panic if `rhs` is 0.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "assert_eq!(100", stringify!($SelfT), ".wrapping_div(10), 10);
+assert_eq!((-128i8).wrapping_div(-1), -128);",
+$EndFeature, "
+```"),
+ #[stable(feature = "num_wrapping", since = "1.2.0")]
+ #[inline]
+ pub fn wrapping_div(self, rhs: Self) -> Self {
+ self.overflowing_div(rhs).0
+ }
}
- /// 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
- ///
- /// ```
- /// assert_eq!(0x10i32.overflowing_shr(4), (0x1, false));
- /// assert_eq!(0x10i32.overflowing_shr(36), (0x1, true));
- /// ```
- #[inline]
- #[stable(feature = "wrapping", since = "1.7.0")]
- pub fn overflowing_shr(self, rhs: u32) -> (Self, bool) {
- (self.wrapping_shr(rhs), (rhs > ($BITS - 1)))
+ doc_comment! {
+ concat!("Wrapping (modular) remainder. Computes `self % rhs`, wrapping around at the
+boundary of the type.
+
+Such wrap-around never actually occurs mathematically; implementation artifacts make `x % y`
+invalid for `MIN / -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:
+
+```
+", $Feature, "assert_eq!(100", stringify!($SelfT), ".wrapping_rem(10), 0);
+assert_eq!((-128i8).wrapping_rem(-1), 0);",
+$EndFeature, "
+```"),
+ #[stable(feature = "num_wrapping", since = "1.2.0")]
+ #[inline]
+ pub fn wrapping_rem(self, rhs: Self) -> Self {
+ self.overflowing_rem(rhs).0
+ }
}
- /// Computes the absolute value of `self`.
- ///
- /// Returns a tuple of the absolute 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:
- ///
- /// ```
- /// assert_eq!(10i8.overflowing_abs(), (10,false));
- /// assert_eq!((-10i8).overflowing_abs(), (10,false));
- /// assert_eq!((-128i8).overflowing_abs(), (-128,true));
- /// ```
- #[stable(feature = "no_panic_abs", since = "1.13.0")]
- #[inline]
- pub fn overflowing_abs(self) -> (Self, bool) {
- if self.is_negative() {
- self.overflowing_neg()
- } else {
- (self, false)
+ doc_comment! {
+ concat!("Wrapping (modular) negation. Computes `-self`, wrapping around at the boundary
+of the type.
+
+The only case where such wrapping can occur is when one negates `MIN` on a signed type (where `MIN`
+is the negative minimal value for the type); this is a positive value that is too large to represent
+in the type. In such a case, this function returns `MIN` itself.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "assert_eq!(100", stringify!($SelfT), ".wrapping_neg(), -100);
+assert_eq!(", stringify!($SelfT), "::min_value().wrapping_neg(), ", stringify!($SelfT),
+"::min_value());",
+$EndFeature, "
+```"),
+ #[stable(feature = "num_wrapping", since = "1.2.0")]
+ #[inline]
+ pub fn wrapping_neg(self) -> Self {
+ self.overflowing_neg().0
}
}
- /// Raises self to the power of `exp`, using exponentiation by squaring.
- ///
- /// # Examples
- ///
- /// Basic usage:
- ///
- /// ```
- /// let x: i32 = 2; // or any other integer type
- ///
- /// assert_eq!(x.pow(4), 16);
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline]
- #[rustc_inherit_overflow_checks]
- pub fn pow(self, mut exp: u32) -> Self {
- let mut base = self;
- let mut acc = 1;
+ doc_comment! {
+ concat!("Panic-free bitwise shift-left; yields `self << mask(rhs)`, where `mask` removes
+any high-order bits of `rhs` that would cause the shift to exceed the bitwidth of the type.
- while exp > 1 {
- if (exp & 1) == 1 {
- acc = acc * base;
+Note that this is *not* the same as a rotate-left; the RHS of a wrapping shift-left is restricted to
+the range of the type, rather than the bits shifted out of the LHS being returned to the other end.
+The primitive integer types all implement a `rotate_left` function, which may be what you want
+instead.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "assert_eq!((-1", stringify!($SelfT), ").wrapping_shl(7), -128);
+assert_eq!((-1", stringify!($SelfT), ").wrapping_shl(128), -1);",
+$EndFeature, "
+```"),
+ #[stable(feature = "num_wrapping", since = "1.2.0")]
+ #[inline]
+ pub fn wrapping_shl(self, rhs: u32) -> Self {
+ unsafe {
+ intrinsics::unchecked_shl(self, (rhs & ($BITS - 1)) as $SelfT)
}
- exp /= 2;
- base = base * base;
}
+ }
- // Deal with the final bit of the exponent separately, since
- // squaring the base afterwards is not necessary and may cause a
- // needless overflow.
- if exp == 1 {
- acc = acc * base;
- }
+ doc_comment! {
+ concat!("Panic-free bitwise shift-right; yields `self >> mask(rhs)`, where `mask`
+removes any high-order bits of `rhs` that would cause the shift to exceed the bitwidth of the type.
- acc
- }
+Note that this is *not* the same as a rotate-right; the RHS of a wrapping shift-right is restricted
+to the range of the type, rather than the bits shifted out of the LHS being returned to the other
+end. The primitive integer types all implement a `rotate_right` function, which may be what you want
+instead.
- /// Computes the absolute value of `self`.
- ///
- /// # Overflow behavior
- ///
- /// The absolute value of `i32::min_value()` cannot be represented as an
- /// `i32`, and attempting to calculate it will cause an overflow. This
- /// means that code in debug mode will trigger a panic on this case and
- /// optimized code will return `i32::min_value()` without a panic.
- ///
- /// # Examples
- ///
- /// Basic usage:
- ///
- /// ```
- /// assert_eq!(10i8.abs(), 10);
- /// assert_eq!((-10i8).abs(), 10);
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline]
- #[rustc_inherit_overflow_checks]
- pub fn abs(self) -> Self {
- if self.is_negative() {
- // Note that the #[inline] above means that the overflow
- // semantics of this negation depend on the crate we're being
- // inlined into.
- -self
- } else {
- self
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "assert_eq!((-128", stringify!($SelfT), ").wrapping_shr(7), -1);
+assert_eq!((-128i16).wrapping_shr(64), -128);",
+$EndFeature, "
+```"),
+ #[stable(feature = "num_wrapping", since = "1.2.0")]
+ #[inline]
+ pub fn wrapping_shr(self, rhs: u32) -> Self {
+ unsafe {
+ intrinsics::unchecked_shr(self, (rhs & ($BITS - 1)) as $SelfT)
+ }
}
}
- /// Returns a number representing sign of `self`.
- ///
- /// - `0` if the number is zero
- /// - `1` if the number is positive
- /// - `-1` if the number is negative
- ///
- /// # Examples
- ///
- /// Basic usage:
- ///
- /// ```
- /// assert_eq!(10i8.signum(), 1);
- /// assert_eq!(0i8.signum(), 0);
- /// assert_eq!((-10i8).signum(), -1);
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline]
- pub fn signum(self) -> Self {
- match self {
- n if n > 0 => 1,
- 0 => 0,
- _ => -1,
+ doc_comment! {
+ concat!("Wrapping (modular) absolute value. Computes `self.abs()`, wrapping around at
+the boundary of the type.
+
+The only case where such wrapping can occur is when one takes the absolute value of the negative
+minimal value for the type this is a positive value that is too large to represent in the type. In
+such a case, this function returns `MIN` itself.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "assert_eq!(100", stringify!($SelfT), ".wrapping_abs(), 100);
+assert_eq!((-100", stringify!($SelfT), ").wrapping_abs(), 100);
+assert_eq!(", stringify!($SelfT), "::min_value().wrapping_abs(), ", stringify!($SelfT),
+"::min_value());
+assert_eq!((-128i8).wrapping_abs() as u8, 128);",
+$EndFeature, "
+```"),
+ #[stable(feature = "no_panic_abs", since = "1.13.0")]
+ #[inline]
+ pub fn wrapping_abs(self) -> Self {
+ if self.is_negative() {
+ self.wrapping_neg()
+ } else {
+ self
+ }
}
}
- /// Returns `true` if `self` is positive and `false` if the number
- /// is zero or negative.
- ///
- /// # Examples
- ///
- /// Basic usage:
- ///
- /// ```
- /// assert!(10i8.is_positive());
- /// assert!(!(-10i8).is_positive());
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline]
- pub fn is_positive(self) -> bool { self > 0 }
+ doc_comment! {
+ concat!("Wrapping (modular) exponentiation. Computes `self.pow(exp)`,
+wrapping around at the boundary of the type.
- /// Returns `true` if `self` is negative and `false` if the number
- /// is zero or positive.
- ///
- /// # Examples
- ///
- /// Basic usage:
- ///
- /// ```
- /// assert!((-10i8).is_negative());
- /// assert!(!10i8.is_negative());
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline]
- pub fn is_negative(self) -> bool { self < 0 }
- }
-}
+# Examples
-#[lang = "i8"]
-impl i8 {
- int_impl! { i8, i8, u8, 8 }
-}
+Basic usage:
-#[lang = "i16"]
-impl i16 {
- int_impl! { i16, i16, u16, 16 }
-}
+```
+#![feature(no_panic_pow)]
+", $Feature, "assert_eq!(3", stringify!($SelfT), ".wrapping_pow(4), 81);
+assert_eq!(3i8.wrapping_pow(5), -13);
+assert_eq!(3i8.wrapping_pow(6), -39);",
+$EndFeature, "
+```"),
+ #[unstable(feature = "no_panic_pow", issue = "48320")]
+ #[inline]
+ pub fn wrapping_pow(self, mut exp: u32) -> Self {
+ let mut base = self;
+ let mut acc: Self = 1;
+
+ while exp > 1 {
+ if (exp & 1) == 1 {
+ acc = acc.wrapping_mul(base);
+ }
+ exp /= 2;
+ base = base.wrapping_mul(base);
+ }
-#[lang = "i32"]
-impl i32 {
- int_impl! { i32, i32, u32, 32 }
-}
+ // Deal with the final bit of the exponent separately, since
+ // squaring the base afterwards is not necessary and may cause a
+ // needless overflow.
+ if exp == 1 {
+ acc = acc.wrapping_mul(base);
+ }
-#[lang = "i64"]
-impl i64 {
- int_impl! { i64, i64, u64, 64 }
-}
+ acc
+ }
+ }
-#[lang = "i128"]
-impl i128 {
- int_impl! { i128, i128, u128, 128 }
-}
+ doc_comment! {
+ concat!("Calculates `self` + `rhs`
-#[cfg(target_pointer_width = "16")]
-#[lang = "isize"]
-impl isize {
- int_impl! { isize, i16, u16, 16 }
-}
+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.
-#[cfg(target_pointer_width = "32")]
-#[lang = "isize"]
-impl isize {
- int_impl! { isize, i32, u32, 32 }
-}
+# Examples
-#[cfg(target_pointer_width = "64")]
-#[lang = "isize"]
-impl isize {
- int_impl! { isize, i64, u64, 64 }
-}
+Basic usage:
-// `Int` + `UnsignedInt` implemented for unsigned integers
-macro_rules! uint_impl {
- ($SelfT:ty, $ActualT:ty, $BITS:expr) => {
- /// Returns the smallest value that can be represented by this integer type.
- ///
- /// # Examples
- ///
- /// Basic usage:
- ///
- /// ```
- /// assert_eq!(u8::min_value(), 0);
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline]
- pub const fn min_value() -> Self { 0 }
+```
+", $Feature, "use std::", stringify!($SelfT), ";
- /// Returns the largest value that can be represented by this integer type.
- ///
- /// # Examples
- ///
- /// Basic usage:
- ///
- /// ```
- /// assert_eq!(u8::max_value(), 255);
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline]
- pub const fn max_value() -> Self { !0 }
+assert_eq!(5", stringify!($SelfT), ".overflowing_add(2), (7, false));
+assert_eq!(", stringify!($SelfT), "::MAX.overflowing_add(1), (", stringify!($SelfT),
+"::MIN, true));", $EndFeature, "
+```"),
+ #[inline]
+ #[stable(feature = "wrapping", since = "1.7.0")]
+ pub fn overflowing_add(self, rhs: Self) -> (Self, bool) {
+ let (a, b) = unsafe {
+ intrinsics::add_with_overflow(self as $ActualT,
+ rhs as $ActualT)
+ };
+ (a as Self, b)
+ }
+ }
- /// Converts a string slice in a given base to an integer.
- ///
- /// The string is expected to be an optional `+` sign
- /// followed by digits.
- /// Leading and trailing whitespace represent an error.
- /// Digits are a subset of these characters, depending on `radix`:
- ///
- /// * `0-9`
- /// * `a-z`
- /// * `A-Z`
- ///
- /// # Panics
- ///
- /// This function panics if `radix` is not in the range from 2 to 36.
- ///
- /// # Examples
- ///
- /// Basic usage:
- ///
- /// ```
- /// assert_eq!(u32::from_str_radix("A", 16), Ok(10));
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- pub fn from_str_radix(src: &str, radix: u32) -> Result<Self, ParseIntError> {
- from_str_radix(src, radix)
+ doc_comment! {
+ concat!("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, "use std::", stringify!($SelfT), ";
+
+assert_eq!(5", stringify!($SelfT), ".overflowing_sub(2), (3, false));
+assert_eq!(", stringify!($SelfT), "::MIN.overflowing_sub(1), (", stringify!($SelfT),
+"::MAX, true));", $EndFeature, "
+```"),
+ #[inline]
+ #[stable(feature = "wrapping", since = "1.7.0")]
+ pub fn overflowing_sub(self, rhs: Self) -> (Self, bool) {
+ let (a, b) = unsafe {
+ intrinsics::sub_with_overflow(self as $ActualT,
+ rhs as $ActualT)
+ };
+ (a as Self, b)
+ }
}
- /// Returns the number of ones in the binary representation of `self`.
- ///
- /// # Examples
- ///
- /// Basic usage:
- ///
- /// ```
- /// let n = 0b01001100u8;
- ///
- /// assert_eq!(n.count_ones(), 3);
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline]
- pub fn count_ones(self) -> u32 {
- unsafe { intrinsics::ctpop(self as $ActualT) as u32 }
+ doc_comment! {
+ concat!("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, "assert_eq!(5", stringify!($SelfT), ".overflowing_mul(2), (10, false));
+assert_eq!(1_000_000_000i32.overflowing_mul(10), (1410065408, true));",
+$EndFeature, "
+```"),
+ #[inline]
+ #[stable(feature = "wrapping", since = "1.7.0")]
+ pub fn overflowing_mul(self, rhs: Self) -> (Self, bool) {
+ let (a, b) = unsafe {
+ intrinsics::mul_with_overflow(self as $ActualT,
+ rhs as $ActualT)
+ };
+ (a as Self, b)
+ }
}
- /// Returns the number of zeros in the binary representation of `self`.
- ///
- /// # Examples
- ///
- /// Basic usage:
- ///
- /// ```
- /// let n = 0b01001100u8;
- ///
- /// assert_eq!(n.count_zeros(), 5);
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline]
- pub fn count_zeros(self) -> u32 {
- (!self).count_ones()
+ doc_comment! {
+ concat!("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, "use std::", stringify!($SelfT), ";
+
+assert_eq!(5", stringify!($SelfT), ".overflowing_div(2), (2, false));
+assert_eq!(", stringify!($SelfT), "::MIN.overflowing_div(-1), (", stringify!($SelfT),
+"::MIN, true));",
+$EndFeature, "
+```"),
+ #[inline]
+ #[stable(feature = "wrapping", since = "1.7.0")]
+ pub fn overflowing_div(self, rhs: Self) -> (Self, bool) {
+ if self == Self::min_value() && rhs == -1 {
+ (self, true)
+ } else {
+ (self / rhs, false)
+ }
+ }
}
- /// Returns the number of leading zeros in the binary representation
- /// of `self`.
- ///
- /// # Examples
- ///
- /// Basic usage:
- ///
- /// ```
- /// let n = 0b0101000u16;
- ///
- /// assert_eq!(n.leading_zeros(), 10);
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline]
- pub fn leading_zeros(self) -> u32 {
- unsafe { intrinsics::ctlz(self as $ActualT) as u32 }
+ doc_comment! {
+ concat!("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, "use std::", stringify!($SelfT), ";
+
+assert_eq!(5", stringify!($SelfT), ".overflowing_rem(2), (1, false));
+assert_eq!(", stringify!($SelfT), "::MIN.overflowing_rem(-1), (0, true));",
+$EndFeature, "
+```"),
+ #[inline]
+ #[stable(feature = "wrapping", since = "1.7.0")]
+ pub fn overflowing_rem(self, rhs: Self) -> (Self, bool) {
+ if self == Self::min_value() && rhs == -1 {
+ (0, true)
+ } else {
+ (self % rhs, false)
+ }
+ }
}
- /// Returns the number of trailing zeros in the binary representation
- /// of `self`.
- ///
- /// # Examples
- ///
- /// Basic usage:
- ///
- /// ```
- /// let n = 0b0101000u16;
- ///
- /// assert_eq!(n.trailing_zeros(), 3);
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline]
- pub fn trailing_zeros(self) -> u32 {
- // As of LLVM 3.6 the codegen for the zero-safe cttz8 intrinsic
- // emits two conditional moves on x86_64. By promoting the value to
- // u16 and setting bit 8, we get better code without any conditional
- // operations.
- // FIXME: There's a LLVM patch (http://reviews.llvm.org/D9284)
- // pending, remove this workaround once LLVM generates better code
- // for cttz8.
- unsafe {
- if $BITS == 8 {
- intrinsics::cttz(self as u16 | 0x100) as u32
+ doc_comment! {
+ concat!("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, "use std::", stringify!($SelfT), ";
+
+assert_eq!(2", stringify!($SelfT), ".overflowing_neg(), (-2, false));
+assert_eq!(", stringify!($SelfT), "::MIN.overflowing_neg(), (", stringify!($SelfT),
+"::MIN, true));", $EndFeature, "
+```"),
+ #[inline]
+ #[stable(feature = "wrapping", since = "1.7.0")]
+ pub fn overflowing_neg(self) -> (Self, bool) {
+ if self == Self::min_value() {
+ (Self::min_value(), true)
} else {
- intrinsics::cttz(self) as u32
+ (-self, false)
}
}
}
- /// Shifts the bits to the left by a specified amount, `n`,
- /// wrapping the truncated bits to the end of the resulting integer.
- ///
- /// Please note this isn't the same operation as `<<`!
- ///
- /// # Examples
- ///
- /// Basic usage:
- ///
- /// ```
- /// let n = 0x0123456789ABCDEFu64;
- /// let m = 0x3456789ABCDEF012u64;
- ///
- /// assert_eq!(n.rotate_left(12), m);
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline]
- pub fn rotate_left(self, n: u32) -> Self {
- // Protect against undefined behaviour for over-long bit shifts
- let n = n % $BITS;
- (self << n) | (self >> (($BITS - n) % $BITS))
+ doc_comment! {
+ concat!("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, "assert_eq!(0x1", stringify!($SelfT),".overflowing_shl(4), (0x10, false));
+assert_eq!(0x1i32.overflowing_shl(36), (0x10, true));",
+$EndFeature, "
+```"),
+ #[inline]
+ #[stable(feature = "wrapping", since = "1.7.0")]
+ pub fn overflowing_shl(self, rhs: u32) -> (Self, bool) {
+ (self.wrapping_shl(rhs), (rhs > ($BITS - 1)))
+ }
}
- /// Shifts the bits to the right by a specified amount, `n`,
- /// wrapping the truncated bits to the beginning of the resulting
- /// integer.
- ///
- /// Please note this isn't the same operation as `>>`!
- ///
- /// # Examples
- ///
- /// Basic usage:
- ///
- /// ```
- /// let n = 0x0123456789ABCDEFu64;
- /// let m = 0xDEF0123456789ABCu64;
- ///
- /// assert_eq!(n.rotate_right(12), m);
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline]
- pub fn rotate_right(self, n: u32) -> Self {
- // Protect against undefined behaviour for over-long bit shifts
- let n = n % $BITS;
- (self >> n) | (self << (($BITS - n) % $BITS))
+ doc_comment! {
+ concat!("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, "assert_eq!(0x10", stringify!($SelfT), ".overflowing_shr(4), (0x1, false));
+assert_eq!(0x10i32.overflowing_shr(36), (0x1, true));",
+$EndFeature, "
+```"),
+ #[inline]
+ #[stable(feature = "wrapping", since = "1.7.0")]
+ pub fn overflowing_shr(self, rhs: u32) -> (Self, bool) {
+ (self.wrapping_shr(rhs), (rhs > ($BITS - 1)))
+ }
}
- /// Reverses the byte order of the integer.
- ///
- /// # Examples
- ///
- /// Basic usage:
- ///
- /// ```
- /// let n: u16 = 0b0000000_01010101;
- /// assert_eq!(n, 85);
- ///
- /// let m = n.swap_bytes();
- ///
- /// assert_eq!(m, 0b01010101_00000000);
- /// assert_eq!(m, 21760);
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline]
- pub fn swap_bytes(self) -> Self {
- unsafe { intrinsics::bswap(self as $ActualT) as Self }
+ doc_comment! {
+ concat!("Computes the absolute value of `self`.
+
+Returns a tuple of the absolute version of self along with a boolean indicating whether an overflow
+happened. If self is the minimum value (e.g. ", stringify!($SelfT), "::MIN for values of type
+ ", stringify!($SelfT), "), then the minimum value will be returned again and true will be returned
+for an overflow happening.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "assert_eq!(10", stringify!($SelfT), ".overflowing_abs(), (10, false));
+assert_eq!((-10", stringify!($SelfT), ").overflowing_abs(), (10, false));
+assert_eq!((", stringify!($SelfT), "::min_value()).overflowing_abs(), (", stringify!($SelfT),
+"::min_value(), true));",
+$EndFeature, "
+```"),
+ #[stable(feature = "no_panic_abs", since = "1.13.0")]
+ #[inline]
+ pub fn overflowing_abs(self) -> (Self, bool) {
+ if self.is_negative() {
+ self.overflowing_neg()
+ } else {
+ (self, false)
+ }
+ }
}
- /// Converts an integer from big endian to the target's endianness.
- ///
- /// On big endian this is a no-op. On little endian the bytes are
- /// swapped.
- ///
- /// # Examples
- ///
- /// Basic usage:
- ///
- /// ```
- /// let n = 0x0123456789ABCDEFu64;
- ///
- /// if cfg!(target_endian = "big") {
- /// assert_eq!(u64::from_be(n), n)
- /// } else {
- /// assert_eq!(u64::from_be(n), n.swap_bytes())
- /// }
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline]
- pub fn from_be(x: Self) -> Self {
- if cfg!(target_endian = "big") { x } else { x.swap_bytes() }
+ doc_comment! {
+ concat!("Raises self to the power of `exp`, using exponentiation by squaring.
+
+Returns a tuple of the exponentiation along with a bool indicating
+whether an overflow happened.
+
+# Examples
+
+Basic usage:
+
+```
+#![feature(no_panic_pow)]
+", $Feature, "assert_eq!(3", stringify!($SelfT), ".overflowing_pow(4), (81, false));
+assert_eq!(3i8.overflowing_pow(5), (-13, true));",
+$EndFeature, "
+```"),
+ #[unstable(feature = "no_panic_pow", issue = "48320")]
+ #[inline]
+ pub fn overflowing_pow(self, mut exp: u32) -> (Self, bool) {
+ let mut base = self;
+ let mut acc: Self = 1;
+ let mut overflown = false;
+ // Scratch space for storing results of overflowing_mul.
+ let mut r;
+
+ while exp > 1 {
+ if (exp & 1) == 1 {
+ r = acc.overflowing_mul(base);
+ acc = r.0;
+ overflown |= r.1;
+ }
+ exp /= 2;
+ r = base.overflowing_mul(base);
+ base = r.0;
+ overflown |= r.1;
+ }
+
+ // Deal with the final bit of the exponent separately, since
+ // squaring the base afterwards is not necessary and may cause a
+ // needless overflow.
+ if exp == 1 {
+ r = acc.overflowing_mul(base);
+ acc = r.0;
+ overflown |= r.1;
+ }
+
+ (acc, overflown)
+ }
}
- /// Converts an integer from little endian to the target's endianness.
- ///
- /// On little endian this is a no-op. On big endian the bytes are
- /// swapped.
- ///
- /// # Examples
- ///
- /// Basic usage:
- ///
- /// ```
- /// let n = 0x0123456789ABCDEFu64;
- ///
- /// if cfg!(target_endian = "little") {
- /// assert_eq!(u64::from_le(n), n)
- /// } else {
- /// assert_eq!(u64::from_le(n), n.swap_bytes())
- /// }
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline]
- pub fn from_le(x: Self) -> Self {
- if cfg!(target_endian = "little") { x } else { x.swap_bytes() }
+ doc_comment! {
+ concat!("Raises self to the power of `exp`, using exponentiation by squaring.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "let x: ", stringify!($SelfT), " = 2; // or any other integer type
+
+assert_eq!(x.pow(5), 32);",
+$EndFeature, "
+```"),
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
+ #[rustc_inherit_overflow_checks]
+ pub fn pow(self, mut exp: u32) -> Self {
+ let mut base = self;
+ let mut acc = 1;
+
+ while exp > 1 {
+ if (exp & 1) == 1 {
+ acc = acc * base;
+ }
+ exp /= 2;
+ base = base * base;
+ }
+
+ // Deal with the final bit of the exponent separately, since
+ // squaring the base afterwards is not necessary and may cause a
+ // needless overflow.
+ if exp == 1 {
+ acc = acc * base;
+ }
+
+ acc
+ }
}
- /// Converts `self` to big endian from the target's endianness.
- ///
- /// On big endian this is a no-op. On little endian the bytes are
- /// swapped.
- ///
- /// # Examples
- ///
- /// Basic usage:
- ///
- /// ```
- /// let n = 0x0123456789ABCDEFu64;
- ///
- /// if cfg!(target_endian = "big") {
- /// assert_eq!(n.to_be(), n)
- /// } else {
- /// assert_eq!(n.to_be(), n.swap_bytes())
- /// }
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline]
- pub fn to_be(self) -> Self { // or not to be?
- if cfg!(target_endian = "big") { self } else { self.swap_bytes() }
+ doc_comment! {
+ concat!("Computes the absolute value of `self`.
+
+# Overflow behavior
+
+The absolute value of `", stringify!($SelfT), "::min_value()` cannot be represented as an
+`", stringify!($SelfT), "`, and attempting to calculate it will cause an overflow. This means that
+code in debug mode will trigger a panic on this case and optimized code will return `",
+stringify!($SelfT), "::min_value()` without a panic.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "assert_eq!(10", stringify!($SelfT), ".abs(), 10);
+assert_eq!((-10", stringify!($SelfT), ").abs(), 10);",
+$EndFeature, "
+```"),
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
+ #[rustc_inherit_overflow_checks]
+ pub fn abs(self) -> Self {
+ if self.is_negative() {
+ // Note that the #[inline] above means that the overflow
+ // semantics of this negation depend on the crate we're being
+ // inlined into.
+ -self
+ } else {
+ self
+ }
+ }
}
- /// Converts `self` to little endian from the target's endianness.
- ///
- /// On little endian this is a no-op. On big endian the bytes are
- /// swapped.
- ///
- /// # Examples
- ///
- /// Basic usage:
- ///
- /// ```
- /// let n = 0x0123456789ABCDEFu64;
- ///
- /// if cfg!(target_endian = "little") {
- /// assert_eq!(n.to_le(), n)
- /// } else {
- /// assert_eq!(n.to_le(), n.swap_bytes())
- /// }
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline]
- pub fn to_le(self) -> Self {
- if cfg!(target_endian = "little") { self } else { self.swap_bytes() }
+ doc_comment! {
+ concat!("Returns a number representing sign of `self`.
+
+ - `0` if the number is zero
+ - `1` if the number is positive
+ - `-1` if the number is negative
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "assert_eq!(10", stringify!($SelfT), ".signum(), 1);
+assert_eq!(0", stringify!($SelfT), ".signum(), 0);
+assert_eq!((-10", stringify!($SelfT), ").signum(), -1);",
+$EndFeature, "
+```"),
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
+ pub fn signum(self) -> Self {
+ match self {
+ n if n > 0 => 1,
+ 0 => 0,
+ _ => -1,
+ }
+ }
}
- /// Checked integer addition. Computes `self + rhs`, returning `None`
- /// if overflow occurred.
- ///
- /// # Examples
- ///
- /// Basic usage:
- ///
- /// ```
- /// assert_eq!(5u16.checked_add(65530), Some(65535));
- /// assert_eq!(6u16.checked_add(65530), None);
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline]
- pub fn checked_add(self, rhs: Self) -> Option<Self> {
- let (a, b) = self.overflowing_add(rhs);
- if b {None} else {Some(a)}
+ doc_comment! {
+ concat!("Returns `true` if `self` is positive and `false` if the number is zero or
+negative.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "assert!(10", stringify!($SelfT), ".is_positive());
+assert!(!(-10", stringify!($SelfT), ").is_positive());",
+$EndFeature, "
+```"),
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
+ pub fn is_positive(self) -> bool { self > 0 }
}
- /// Checked integer subtraction. Computes `self - rhs`, returning
- /// `None` if overflow occurred.
- ///
- /// # Examples
- ///
- /// Basic usage:
- ///
- /// ```
- /// assert_eq!(1u8.checked_sub(1), Some(0));
- /// assert_eq!(0u8.checked_sub(1), None);
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline]
- pub fn checked_sub(self, rhs: Self) -> Option<Self> {
- let (a, b) = self.overflowing_sub(rhs);
- if b {None} else {Some(a)}
+ doc_comment! {
+ concat!("Returns `true` if `self` is negative and `false` if the number is zero or
+positive.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "assert!((-10", stringify!($SelfT), ").is_negative());
+assert!(!10", stringify!($SelfT), ".is_negative());",
+$EndFeature, "
+```"),
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
+ pub fn is_negative(self) -> bool { self < 0 }
}
+ }
+}
- /// Checked integer multiplication. Computes `self * rhs`, returning
- /// `None` if overflow occurred.
- ///
- /// # Examples
- ///
- /// Basic usage:
- ///
- /// ```
- /// assert_eq!(5u8.checked_mul(51), Some(255));
- /// assert_eq!(5u8.checked_mul(52), None);
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline]
- pub fn checked_mul(self, rhs: Self) -> Option<Self> {
- let (a, b) = self.overflowing_mul(rhs);
- if b {None} else {Some(a)}
+#[lang = "i8"]
+impl i8 {
+ int_impl! { i8, i8, u8, 8, -128, 127, "", "" }
+}
+
+#[lang = "i16"]
+impl i16 {
+ int_impl! { i16, i16, u16, 16, -32768, 32767, "", "" }
+}
+
+#[lang = "i32"]
+impl i32 {
+ int_impl! { i32, i32, u32, 32, -2147483648, 2147483647, "", "" }
+}
+
+#[lang = "i64"]
+impl i64 {
+ int_impl! { i64, i64, u64, 64, -9223372036854775808, 9223372036854775807, "", "" }
+}
+
+#[lang = "i128"]
+impl i128 {
+ int_impl! { i128, i128, u128, 128, -170141183460469231731687303715884105728,
+ 170141183460469231731687303715884105727, "", "" }
+}
+
+#[cfg(target_pointer_width = "16")]
+#[lang = "isize"]
+impl isize {
+ int_impl! { isize, i16, u16, 16, -32768, 32767, "", "" }
+}
+
+#[cfg(target_pointer_width = "32")]
+#[lang = "isize"]
+impl isize {
+ int_impl! { isize, i32, u32, 32, -2147483648, 2147483647, "", "" }
+}
+
+#[cfg(target_pointer_width = "64")]
+#[lang = "isize"]
+impl isize {
+ int_impl! { isize, i64, u64, 64, -9223372036854775808, 9223372036854775807, "", "" }
+}
+
+// `Int` + `UnsignedInt` implemented for unsigned integers
+macro_rules! uint_impl {
+ ($SelfT:ty, $ActualT:ty, $BITS:expr, $MaxV:expr, $Feature:expr, $EndFeature:expr) => {
+ doc_comment! {
+ concat!("Returns the smallest value that can be represented by this integer type.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "assert_eq!(", stringify!($SelfT), "::min_value(), 0);", $EndFeature, "
+```"),
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
+ pub const fn min_value() -> Self { 0 }
}
- /// Checked integer division. Computes `self / rhs`, returning `None`
- /// if `rhs == 0`.
- ///
- /// # Examples
- ///
- /// Basic usage:
- ///
- /// ```
- /// assert_eq!(128u8.checked_div(2), Some(64));
- /// assert_eq!(1u8.checked_div(0), None);
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline]
- pub fn checked_div(self, rhs: Self) -> Option<Self> {
- match rhs {
- 0 => None,
- rhs => Some(unsafe { intrinsics::unchecked_div(self, rhs) }),
- }
+ doc_comment! {
+ concat!("Returns the largest value that can be represented by this integer type.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "assert_eq!(", stringify!($SelfT), "::max_value(), ",
+stringify!($MaxV), ");", $EndFeature, "
+```"),
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
+ pub const fn max_value() -> Self { !0 }
}
- /// Checked integer remainder. Computes `self % rhs`, returning `None`
- /// if `rhs == 0`.
- ///
- /// # Examples
- ///
- /// Basic usage:
- ///
- /// ```
- /// assert_eq!(5u32.checked_rem(2), Some(1));
- /// assert_eq!(5u32.checked_rem(0), None);
- /// ```
- #[stable(feature = "wrapping", since = "1.7.0")]
- #[inline]
- pub fn checked_rem(self, rhs: Self) -> Option<Self> {
- if rhs == 0 {
- None
- } else {
- Some(unsafe { intrinsics::unchecked_rem(self, rhs) })
+ doc_comment! {
+ concat!("Converts a string slice in a given base to an integer.
+
+The string is expected to be an optional `+` sign
+followed by digits.
+Leading and trailing whitespace represent an error.
+Digits are a subset of these characters, depending on `radix`:
+
+* `0-9`
+* `a-z`
+* `A-Z`
+
+# Panics
+
+This function panics if `radix` is not in the range from 2 to 36.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "assert_eq!(", stringify!($SelfT), "::from_str_radix(\"A\", 16), Ok(10));",
+$EndFeature, "
+```"),
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub fn from_str_radix(src: &str, radix: u32) -> Result<Self, ParseIntError> {
+ from_str_radix(src, radix)
}
}
- /// Checked negation. Computes `-self`, returning `None` unless `self ==
- /// 0`.
- ///
- /// Note that negating any positive integer will overflow.
- ///
- /// # Examples
- ///
- /// Basic usage:
- ///
- /// ```
- /// assert_eq!(0u32.checked_neg(), Some(0));
- /// assert_eq!(1u32.checked_neg(), None);
- /// ```
- #[stable(feature = "wrapping", since = "1.7.0")]
- #[inline]
- pub fn checked_neg(self) -> Option<Self> {
- let (a, b) = self.overflowing_neg();
- if b {None} else {Some(a)}
+ doc_comment! {
+ concat!("Returns the number of ones in the binary representation of `self`.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "let n = 0b01001100", stringify!($SelfT), ";
+
+assert_eq!(n.count_ones(), 3);", $EndFeature, "
+```"),
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
+ pub fn count_ones(self) -> u32 {
+ unsafe { intrinsics::ctpop(self as $ActualT) as u32 }
+ }
}
- /// 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:
- ///
- /// ```
- /// assert_eq!(0x10u32.checked_shl(4), Some(0x100));
- /// assert_eq!(0x10u32.checked_shl(33), None);
- /// ```
- #[stable(feature = "wrapping", since = "1.7.0")]
- #[inline]
- pub fn checked_shl(self, rhs: u32) -> Option<Self> {
- let (a, b) = self.overflowing_shl(rhs);
- if b {None} else {Some(a)}
+ doc_comment! {
+ concat!("Returns the number of zeros in the binary representation of `self`.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "assert_eq!(", stringify!($SelfT), "::max_value().count_zeros(), 0);", $EndFeature, "
+```"),
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
+ pub fn count_zeros(self) -> u32 {
+ (!self).count_ones()
+ }
}
- /// 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:
- ///
- /// ```
- /// assert_eq!(0x10u32.checked_shr(4), Some(0x1));
- /// assert_eq!(0x10u32.checked_shr(33), None);
- /// ```
- #[stable(feature = "wrapping", since = "1.7.0")]
- #[inline]
- pub fn checked_shr(self, rhs: u32) -> Option<Self> {
- let (a, b) = self.overflowing_shr(rhs);
- if b {None} else {Some(a)}
+ doc_comment! {
+ concat!("Returns the number of leading zeros in the binary representation of `self`.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "let n = ", stringify!($SelfT), "::max_value() >> 2;
+
+assert_eq!(n.leading_zeros(), 2);", $EndFeature, "
+```"),
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
+ pub fn leading_zeros(self) -> u32 {
+ unsafe { intrinsics::ctlz(self as $ActualT) as u32 }
+ }
}
- /// Saturating integer addition. Computes `self + rhs`, saturating at
- /// the numeric bounds instead of overflowing.
- ///
- /// # Examples
- ///
- /// Basic usage:
- ///
- /// ```
- /// assert_eq!(100u8.saturating_add(1), 101);
- /// assert_eq!(200u8.saturating_add(127), 255);
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline]
- pub fn saturating_add(self, rhs: Self) -> Self {
- match self.checked_add(rhs) {
- Some(x) => x,
- None => Self::max_value(),
+ doc_comment! {
+ concat!("Returns the number of trailing zeros in the binary representation
+of `self`.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "let n = 0b0101000", stringify!($SelfT), ";
+
+assert_eq!(n.trailing_zeros(), 3);", $EndFeature, "
+```"),
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
+ pub fn trailing_zeros(self) -> u32 {
+ // As of LLVM 3.6 the codegen for the zero-safe cttz8 intrinsic
+ // emits two conditional moves on x86_64. By promoting the value to
+ // u16 and setting bit 8, we get better code without any conditional
+ // operations.
+ // FIXME: There's a LLVM patch (http://reviews.llvm.org/D9284)
+ // pending, remove this workaround once LLVM generates better code
+ // for cttz8.
+ unsafe {
+ if $BITS == 8 {
+ intrinsics::cttz(self as u16 | 0x100) as u32
+ } else {
+ intrinsics::cttz(self) as u32
+ }
+ }
}
}
- /// Saturating integer subtraction. Computes `self - rhs`, saturating
- /// at the numeric bounds instead of overflowing.
+ /// Shifts the bits to the left by a specified amount, `n`,
+ /// wrapping the truncated bits to the end of the resulting integer.
+ ///
+ /// Please note this isn't the same operation as `<<`!
///
/// # Examples
///
/// Basic usage:
///
+ /// Please note that this example is shared between integer types.
+ /// Which explains why `u64` is used here.
+ ///
/// ```
- /// assert_eq!(100u8.saturating_sub(27), 73);
- /// assert_eq!(13u8.saturating_sub(127), 0);
+ /// let n = 0x0123456789ABCDEFu64;
+ /// let m = 0x3456789ABCDEF012u64;
+ ///
+ /// assert_eq!(n.rotate_left(12), m);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
- pub fn saturating_sub(self, rhs: Self) -> Self {
- match self.checked_sub(rhs) {
- Some(x) => x,
- None => Self::min_value(),
- }
+ pub fn rotate_left(self, n: u32) -> Self {
+ // Protect against undefined behaviour for over-long bit shifts
+ let n = n % $BITS;
+ (self << n) | (self >> (($BITS - n) % $BITS))
}
- /// Saturating integer multiplication. Computes `self * rhs`,
- /// saturating at the numeric bounds instead of overflowing.
+ /// Shifts the bits to the right by a specified amount, `n`,
+ /// wrapping the truncated bits to the beginning of the resulting
+ /// integer.
+ ///
+ /// Please note this isn't the same operation as `>>`!
///
/// # Examples
///
/// Basic usage:
///
+ /// Please note that this example is shared between integer types.
+ /// Which explains why `u64` is used here.
+ ///
/// ```
- /// use std::u32;
+ /// let n = 0x0123456789ABCDEFu64;
+ /// let m = 0xDEF0123456789ABCu64;
///
- /// assert_eq!(100u32.saturating_mul(127), 12700);
- /// assert_eq!((1u32 << 23).saturating_mul(1 << 23), u32::MAX);
+ /// assert_eq!(n.rotate_right(12), m);
/// ```
- #[stable(feature = "wrapping", since = "1.7.0")]
+ #[stable(feature = "rust1", since = "1.0.0")]
#[inline]
- pub fn saturating_mul(self, rhs: Self) -> Self {
- self.checked_mul(rhs).unwrap_or(Self::max_value())
+ pub fn rotate_right(self, n: u32) -> Self {
+ // Protect against undefined behaviour for over-long bit shifts
+ let n = n % $BITS;
+ (self >> n) | (self << (($BITS - n) % $BITS))
}
- /// Wrapping (modular) addition. Computes `self + rhs`,
- /// wrapping around at the boundary of the type.
+ /// Reverses the byte order of the integer.
///
/// # Examples
///
/// Basic usage:
///
+ /// Please note that this example is shared between integer types.
+ /// Which explains why `u16` is used here.
+ ///
/// ```
- /// assert_eq!(200u8.wrapping_add(55), 255);
- /// assert_eq!(200u8.wrapping_add(155), 99);
+ /// let n: u16 = 0b0000000_01010101;
+ /// assert_eq!(n, 85);
+ ///
+ /// let m = n.swap_bytes();
+ ///
+ /// assert_eq!(m, 0b01010101_00000000);
+ /// assert_eq!(m, 21760);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
- pub fn wrapping_add(self, rhs: Self) -> Self {
- unsafe {
- intrinsics::overflowing_add(self, rhs)
- }
+ pub fn swap_bytes(self) -> Self {
+ unsafe { intrinsics::bswap(self as $ActualT) as Self }
}
- /// Wrapping (modular) subtraction. Computes `self - rhs`,
- /// wrapping around at the boundary of the type.
+ /// Reverses the bit pattern of the integer.
///
/// # Examples
///
/// Basic usage:
///
+ /// Please note that this example is shared between integer types.
+ /// Which explains why `u16` is used here.
+ ///
/// ```
- /// assert_eq!(100u8.wrapping_sub(100), 0);
- /// assert_eq!(100u8.wrapping_sub(155), 201);
+ /// #![feature(reverse_bits)]
+ ///
+ /// let n: u16 = 0b0000000_01010101;
+ /// assert_eq!(n, 85);
+ ///
+ /// let m = n.reverse_bits();
+ ///
+ /// assert_eq!(m, 0b10101010_00000000);
+ /// assert_eq!(m, 43520);
/// ```
- #[stable(feature = "rust1", since = "1.0.0")]
+ #[unstable(feature = "reverse_bits", issue = "48763")]
+ #[cfg(not(stage0))]
#[inline]
- pub fn wrapping_sub(self, rhs: Self) -> Self {
- unsafe {
- intrinsics::overflowing_sub(self, rhs)
+ pub fn reverse_bits(self) -> Self {
+ unsafe { intrinsics::bitreverse(self as $ActualT) as Self }
+ }
+
+ doc_comment! {
+ concat!("Converts an integer from big endian to the target's endianness.
+
+On big endian this is a no-op. On little endian the bytes are
+swapped.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "let n = 0x1A", stringify!($SelfT), ";
+
+if cfg!(target_endian = \"big\") {
+ assert_eq!(", stringify!($SelfT), "::from_be(n), n)
+} else {
+ assert_eq!(", stringify!($SelfT), "::from_be(n), n.swap_bytes())
+}", $EndFeature, "
+```"),
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
+ pub fn from_be(x: Self) -> Self {
+ if cfg!(target_endian = "big") { x } else { x.swap_bytes() }
+ }
+ }
+
+ doc_comment! {
+ concat!("Converts an integer from little endian to the target's endianness.
+
+On little endian this is a no-op. On big endian the bytes are
+swapped.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "let n = 0x1A", stringify!($SelfT), ";
+
+if cfg!(target_endian = \"little\") {
+ assert_eq!(", stringify!($SelfT), "::from_le(n), n)
+} else {
+ assert_eq!(", stringify!($SelfT), "::from_le(n), n.swap_bytes())
+}", $EndFeature, "
+```"),
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
+ pub fn from_le(x: Self) -> Self {
+ if cfg!(target_endian = "little") { x } else { x.swap_bytes() }
+ }
+ }
+
+ doc_comment! {
+ concat!("Converts `self` to big endian from the target's endianness.
+
+On big endian this is a no-op. On little endian the bytes are
+swapped.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "let n = 0x1A", stringify!($SelfT), ";
+
+if cfg!(target_endian = \"big\") {
+ assert_eq!(n.to_be(), n)
+} else {
+ assert_eq!(n.to_be(), n.swap_bytes())
+}", $EndFeature, "
+```"),
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
+ pub fn to_be(self) -> Self { // or not to be?
+ if cfg!(target_endian = "big") { self } else { self.swap_bytes() }
+ }
+ }
+
+ doc_comment! {
+ concat!("Converts `self` to little endian from the target's endianness.
+
+On little endian this is a no-op. On big endian the bytes are
+swapped.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "let n = 0x1A", stringify!($SelfT), ";
+
+if cfg!(target_endian = \"little\") {
+ assert_eq!(n.to_le(), n)
+} else {
+ assert_eq!(n.to_le(), n.swap_bytes())
+}", $EndFeature, "
+```"),
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
+ pub fn to_le(self) -> Self {
+ if cfg!(target_endian = "little") { self } else { self.swap_bytes() }
+ }
+ }
+
+ doc_comment! {
+ concat!("Checked integer addition. Computes `self + rhs`, returning `None`
+if overflow occurred.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "assert_eq!((", stringify!($SelfT), "::max_value() - 2).checked_add(1), ",
+"Some(", stringify!($SelfT), "::max_value() - 1));
+assert_eq!((", stringify!($SelfT), "::max_value() - 2).checked_add(3),None);", $EndFeature, "
+```"),
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
+ pub fn checked_add(self, rhs: Self) -> Option<Self> {
+ let (a, b) = self.overflowing_add(rhs);
+ if b {None} else {Some(a)}
+ }
+ }
+
+ doc_comment! {
+ concat!("Checked integer subtraction. Computes `self - rhs`, returning
+`None` if overflow occurred.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "assert_eq!(1", stringify!($SelfT), ".checked_sub(1), Some(0));
+assert_eq!(0", stringify!($SelfT), ".checked_sub(1), None);", $EndFeature, "
+```"),
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
+ pub fn checked_sub(self, rhs: Self) -> Option<Self> {
+ let (a, b) = self.overflowing_sub(rhs);
+ if b {None} else {Some(a)}
+ }
+ }
+
+ doc_comment! {
+ concat!("Checked integer multiplication. Computes `self * rhs`, returning
+`None` if overflow occurred.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "assert_eq!(5", stringify!($SelfT), ".checked_mul(1), Some(5));
+assert_eq!(", stringify!($SelfT), "::max_value().checked_mul(2), None);", $EndFeature, "
+```"),
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
+ pub fn checked_mul(self, rhs: Self) -> Option<Self> {
+ let (a, b) = self.overflowing_mul(rhs);
+ if b {None} else {Some(a)}
+ }
+ }
+
+ doc_comment! {
+ concat!("Checked integer division. Computes `self / rhs`, returning `None`
+if `rhs == 0`.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "assert_eq!(128", stringify!($SelfT), ".checked_div(2), Some(64));
+assert_eq!(1", stringify!($SelfT), ".checked_div(0), None);", $EndFeature, "
+```"),
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
+ pub fn checked_div(self, rhs: Self) -> Option<Self> {
+ match rhs {
+ 0 => None,
+ rhs => Some(unsafe { intrinsics::unchecked_div(self, rhs) }),
+ }
+ }
+ }
+
+ doc_comment! {
+ concat!("Checked integer remainder. Computes `self % rhs`, returning `None`
+if `rhs == 0`.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "assert_eq!(5", stringify!($SelfT), ".checked_rem(2), Some(1));
+assert_eq!(5", stringify!($SelfT), ".checked_rem(0), None);", $EndFeature, "
+```"),
+ #[stable(feature = "wrapping", since = "1.7.0")]
+ #[inline]
+ pub fn checked_rem(self, rhs: Self) -> Option<Self> {
+ if rhs == 0 {
+ None
+ } else {
+ Some(unsafe { intrinsics::unchecked_rem(self, rhs) })
+ }
+ }
+ }
+
+ doc_comment! {
+ concat!("Checked negation. Computes `-self`, returning `None` unless `self ==
+0`.
+
+Note that negating any positive integer will overflow.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "assert_eq!(0", stringify!($SelfT), ".checked_neg(), Some(0));
+assert_eq!(1", stringify!($SelfT), ".checked_neg(), None);", $EndFeature, "
+```"),
+ #[stable(feature = "wrapping", since = "1.7.0")]
+ #[inline]
+ pub fn checked_neg(self) -> Option<Self> {
+ let (a, b) = self.overflowing_neg();
+ if b {None} else {Some(a)}
+ }
+ }
+
+ doc_comment! {
+ concat!("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, "assert_eq!(0x1", stringify!($SelfT), ".checked_shl(4), Some(0x10));
+assert_eq!(0x10", stringify!($SelfT), ".checked_shl(129), None);", $EndFeature, "
+```"),
+ #[stable(feature = "wrapping", since = "1.7.0")]
+ #[inline]
+ pub fn checked_shl(self, rhs: u32) -> Option<Self> {
+ let (a, b) = self.overflowing_shl(rhs);
+ if b {None} else {Some(a)}
+ }
+ }
+
+ doc_comment! {
+ concat!("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, "assert_eq!(0x10", stringify!($SelfT), ".checked_shr(4), Some(0x1));
+assert_eq!(0x10", stringify!($SelfT), ".checked_shr(129), None);", $EndFeature, "
+```"),
+ #[stable(feature = "wrapping", since = "1.7.0")]
+ #[inline]
+ pub fn checked_shr(self, rhs: u32) -> Option<Self> {
+ let (a, b) = self.overflowing_shr(rhs);
+ if b {None} else {Some(a)}
+ }
+ }
+
+ doc_comment! {
+ concat!("Checked exponentiation. Computes `self.pow(exp)`, returning `None` if
+overflow occurred.
+
+# Examples
+
+Basic usage:
+
+```
+#![feature(no_panic_pow)]
+", $Feature, "assert_eq!(2", stringify!($SelfT), ".checked_pow(5), Some(32));
+assert_eq!(", stringify!($SelfT), "::max_value().checked_pow(2), None);", $EndFeature, "
+```"),
+ #[unstable(feature = "no_panic_pow", issue = "48320")]
+ #[inline]
+ pub fn checked_pow(self, mut exp: u32) -> Option<Self> {
+ let mut base = self;
+ let mut acc: Self = 1;
+
+ while exp > 1 {
+ if (exp & 1) == 1 {
+ acc = acc.checked_mul(base)?;
+ }
+ exp /= 2;
+ base = base.checked_mul(base)?;
+ }
+
+ // Deal with the final bit of the exponent separately, since
+ // squaring the base afterwards is not necessary and may cause a
+ // needless overflow.
+ if exp == 1 {
+ acc = acc.checked_mul(base)?;
+ }
+
+ Some(acc)
+ }
+ }
+
+ doc_comment! {
+ concat!("Saturating integer addition. Computes `self + rhs`, saturating at
+the numeric bounds instead of overflowing.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "assert_eq!(100", stringify!($SelfT), ".saturating_add(1), 101);
+assert_eq!(200u8.saturating_add(127), 255);", $EndFeature, "
+```"),
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
+ pub fn saturating_add(self, rhs: Self) -> Self {
+ match self.checked_add(rhs) {
+ Some(x) => x,
+ None => Self::max_value(),
+ }
+ }
+ }
+
+ doc_comment! {
+ concat!("Saturating integer subtraction. Computes `self - rhs`, saturating
+at the numeric bounds instead of overflowing.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "assert_eq!(100", stringify!($SelfT), ".saturating_sub(27), 73);
+assert_eq!(13", stringify!($SelfT), ".saturating_sub(127), 0);", $EndFeature, "
+```"),
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
+ pub fn saturating_sub(self, rhs: Self) -> Self {
+ match self.checked_sub(rhs) {
+ Some(x) => x,
+ None => Self::min_value(),
+ }
+ }
+ }
+
+ doc_comment! {
+ concat!("Saturating integer multiplication. Computes `self * rhs`,
+saturating at the numeric bounds instead of overflowing.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "use std::", stringify!($SelfT), ";
+
+assert_eq!(2", stringify!($SelfT), ".saturating_mul(10), 20);
+assert_eq!((", stringify!($SelfT), "::MAX).saturating_mul(10), ", stringify!($SelfT),
+"::MAX);", $EndFeature, "
+```"),
+ #[stable(feature = "wrapping", since = "1.7.0")]
+ #[inline]
+ pub fn saturating_mul(self, rhs: Self) -> Self {
+ self.checked_mul(rhs).unwrap_or(Self::max_value())
+ }
+ }
+
+ doc_comment! {
+ concat!("Saturating integer exponentiation. Computes `self.pow(exp)`,
+saturating at the numeric bounds instead of overflowing.
+
+# Examples
+
+Basic usage:
+
+```
+#![feature(no_panic_pow)]
+", $Feature, "use std::", stringify!($SelfT), ";
+
+assert_eq!(4", stringify!($SelfT), ".saturating_pow(3), 64);
+assert_eq!(", stringify!($SelfT), "::MAX.saturating_pow(2), ", stringify!($SelfT), "::MAX);",
+$EndFeature, "
+```"),
+ #[unstable(feature = "no_panic_pow", issue = "48320")]
+ #[inline]
+ pub fn saturating_pow(self, exp: u32) -> Self {
+ match self.checked_pow(exp) {
+ Some(x) => x,
+ None => Self::max_value(),
+ }
+ }
+ }
+
+ doc_comment! {
+ concat!("Wrapping (modular) addition. Computes `self + rhs`,
+wrapping around at the boundary of the type.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "assert_eq!(200", stringify!($SelfT), ".wrapping_add(55), 255);
+assert_eq!(200", stringify!($SelfT), ".wrapping_add(", stringify!($SelfT), "::max_value()), 199);",
+$EndFeature, "
+```"),
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
+ pub fn wrapping_add(self, rhs: Self) -> Self {
+ unsafe {
+ intrinsics::overflowing_add(self, rhs)
+ }
+ }
+ }
+
+ doc_comment! {
+ concat!("Wrapping (modular) subtraction. Computes `self - rhs`,
+wrapping around at the boundary of the type.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "assert_eq!(100", stringify!($SelfT), ".wrapping_sub(100), 0);
+assert_eq!(100", stringify!($SelfT), ".wrapping_sub(", stringify!($SelfT), "::max_value()), 101);",
+$EndFeature, "
+```"),
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
+ pub fn wrapping_sub(self, rhs: Self) -> Self {
+ unsafe {
+ intrinsics::overflowing_sub(self, rhs)
+ }
}
}
///
/// Basic usage:
///
+ /// Please note that this example is shared between integer types.
+ /// Which explains why `u8` is used here.
+ ///
/// ```
/// assert_eq!(10u8.wrapping_mul(12), 120);
/// assert_eq!(25u8.wrapping_mul(12), 44);
}
}
- /// Wrapping (modular) division. Computes `self / rhs`.
- /// Wrapped division on unsigned types is just normal division.
- /// There's no way wrapping could ever happen.
- /// This function exists, so that all operations
- /// are accounted for in the wrapping operations.
- ///
- /// # Examples
- ///
- /// Basic usage:
- ///
- /// ```
- /// assert_eq!(100u8.wrapping_div(10), 10);
- /// ```
- #[stable(feature = "num_wrapping", since = "1.2.0")]
- #[inline]
- pub fn wrapping_div(self, rhs: Self) -> Self {
- self / rhs
- }
+ doc_comment! {
+ concat!("Wrapping (modular) division. Computes `self / rhs`.
+Wrapped division on unsigned types is just normal division.
+There's no way wrapping could ever happen.
+This function exists, so that all operations
+are accounted for in the wrapping operations.
- /// Wrapping (modular) remainder. Computes `self % rhs`.
- /// Wrapped remainder calculation on unsigned types is
- /// just the regular remainder calculation.
- /// There's no way wrapping could ever happen.
- /// This function exists, so that all operations
- /// are accounted for in the wrapping operations.
- ///
- /// # Examples
- ///
- /// Basic usage:
- ///
- /// ```
- /// assert_eq!(100u8.wrapping_rem(10), 0);
- /// ```
- #[stable(feature = "num_wrapping", since = "1.2.0")]
- #[inline]
- pub fn wrapping_rem(self, rhs: Self) -> Self {
- self % rhs
- }
+# Examples
- /// Wrapping (modular) negation. Computes `-self`,
- /// wrapping around at the boundary of the type.
- ///
- /// Since unsigned types do not have negative equivalents
- /// all applications of this function will wrap (except for `-0`).
- /// For values smaller than the corresponding signed type's maximum
- /// the result is the same as casting the corresponding signed value.
- /// Any larger values are equivalent to `MAX + 1 - (val - MAX - 1)` where
- /// `MAX` is the corresponding signed type's maximum.
- ///
- /// # Examples
- ///
- /// Basic usage:
- ///
- /// ```
- /// assert_eq!(100u8.wrapping_neg(), 156);
- /// assert_eq!(0u8.wrapping_neg(), 0);
- /// assert_eq!(180u8.wrapping_neg(), 76);
- /// assert_eq!(180u8.wrapping_neg(), (127 + 1) - (180u8 - (127 + 1)));
- /// ```
- #[stable(feature = "num_wrapping", since = "1.2.0")]
- #[inline]
- pub fn wrapping_neg(self) -> Self {
- self.overflowing_neg().0
+Basic usage:
+
+```
+", $Feature, "assert_eq!(100", stringify!($SelfT), ".wrapping_div(10), 10);", $EndFeature, "
+```"),
+ #[stable(feature = "num_wrapping", since = "1.2.0")]
+ #[inline]
+ pub fn wrapping_div(self, rhs: Self) -> Self {
+ self / rhs
+ }
}
- /// Panic-free bitwise shift-left; yields `self << mask(rhs)`,
- /// where `mask` removes any high-order bits of `rhs` that
- /// would cause the shift to exceed the bitwidth of the type.
- ///
- /// Note that this is *not* the same as a rotate-left; the
- /// RHS of a wrapping shift-left is restricted to the range
- /// of the type, rather than the bits shifted out of the LHS
- /// being returned to the other end. The primitive integer
- /// types all implement a `rotate_left` function, which may
- /// be what you want instead.
- ///
- /// # Examples
- ///
- /// Basic usage:
- ///
- /// ```
- /// assert_eq!(1u8.wrapping_shl(7), 128);
- /// assert_eq!(1u8.wrapping_shl(8), 1);
- /// ```
- #[stable(feature = "num_wrapping", since = "1.2.0")]
- #[inline]
- pub fn wrapping_shl(self, rhs: u32) -> Self {
- unsafe {
- intrinsics::unchecked_shl(self, (rhs & ($BITS - 1)) as $SelfT)
+ doc_comment! {
+ concat!("Wrapping (modular) remainder. Computes `self % rhs`.
+Wrapped remainder calculation on unsigned types is
+just the regular remainder calculation.
+There's no way wrapping could ever happen.
+This function exists, so that all operations
+are accounted for in the wrapping operations.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "assert_eq!(100", stringify!($SelfT), ".wrapping_rem(10), 0);", $EndFeature, "
+```"),
+ #[stable(feature = "num_wrapping", since = "1.2.0")]
+ #[inline]
+ pub fn wrapping_rem(self, rhs: Self) -> Self {
+ self % rhs
}
}
- /// Panic-free bitwise shift-right; yields `self >> mask(rhs)`,
- /// where `mask` removes any high-order bits of `rhs` that
- /// would cause the shift to exceed the bitwidth of the type.
+ /// Wrapping (modular) negation. Computes `-self`,
+ /// wrapping around at the boundary of the type.
///
- /// Note that this is *not* the same as a rotate-right; the
- /// RHS of a wrapping shift-right is restricted to the range
- /// of the type, rather than the bits shifted out of the LHS
- /// being returned to the other end. The primitive integer
- /// types all implement a `rotate_right` function, which may
- /// be what you want instead.
+ /// Since unsigned types do not have negative equivalents
+ /// all applications of this function will wrap (except for `-0`).
+ /// For values smaller than the corresponding signed type's maximum
+ /// the result is the same as casting the corresponding signed value.
+ /// Any larger values are equivalent to `MAX + 1 - (val - MAX - 1)` where
+ /// `MAX` is the corresponding signed type's maximum.
///
/// # Examples
///
/// Basic usage:
///
+ /// Please note that this example is shared between integer types.
+ /// Which explains why `i8` is used here.
+ ///
/// ```
- /// assert_eq!(128u8.wrapping_shr(7), 1);
- /// assert_eq!(128u8.wrapping_shr(8), 128);
+ /// assert_eq!(100i8.wrapping_neg(), -100);
+ /// assert_eq!((-128i8).wrapping_neg(), -128);
/// ```
#[stable(feature = "num_wrapping", since = "1.2.0")]
#[inline]
- pub fn wrapping_shr(self, rhs: u32) -> Self {
- unsafe {
- intrinsics::unchecked_shr(self, (rhs & ($BITS - 1)) as $SelfT)
+ pub fn wrapping_neg(self) -> Self {
+ self.overflowing_neg().0
+ }
+
+ doc_comment! {
+ concat!("Panic-free bitwise shift-left; yields `self << mask(rhs)`,
+where `mask` removes any high-order bits of `rhs` that
+would cause the shift to exceed the bitwidth of the type.
+
+Note that this is *not* the same as a rotate-left; the
+RHS of a wrapping shift-left is restricted to the range
+of the type, rather than the bits shifted out of the LHS
+being returned to the other end. The primitive integer
+types all implement a `rotate_left` function, which may
+be what you want instead.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "assert_eq!(1", stringify!($SelfT), ".wrapping_shl(7), 128);
+assert_eq!(1", stringify!($SelfT), ".wrapping_shl(128), 1);", $EndFeature, "
+```"),
+ #[stable(feature = "num_wrapping", since = "1.2.0")]
+ #[inline]
+ pub fn wrapping_shl(self, rhs: u32) -> Self {
+ unsafe {
+ intrinsics::unchecked_shl(self, (rhs & ($BITS - 1)) as $SelfT)
+ }
}
}
- /// 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
- ///
- /// ```
- /// use std::u32;
- ///
- /// assert_eq!(5u32.overflowing_add(2), (7, false));
- /// assert_eq!(u32::MAX.overflowing_add(1), (0, true));
- /// ```
- #[inline]
- #[stable(feature = "wrapping", since = "1.7.0")]
- pub fn overflowing_add(self, rhs: Self) -> (Self, bool) {
- let (a, b) = unsafe {
- intrinsics::add_with_overflow(self as $ActualT,
- rhs as $ActualT)
- };
- (a as Self, b)
+ doc_comment! {
+ concat!("Panic-free bitwise shift-right; yields `self >> mask(rhs)`,
+where `mask` removes any high-order bits of `rhs` that
+would cause the shift to exceed the bitwidth of the type.
+
+Note that this is *not* the same as a rotate-right; the
+RHS of a wrapping shift-right is restricted to the range
+of the type, rather than the bits shifted out of the LHS
+being returned to the other end. The primitive integer
+types all implement a `rotate_right` function, which may
+be what you want instead.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "assert_eq!(128", stringify!($SelfT), ".wrapping_shr(7), 1);
+assert_eq!(128", stringify!($SelfT), ".wrapping_shr(128), 128);", $EndFeature, "
+```"),
+ #[stable(feature = "num_wrapping", since = "1.2.0")]
+ #[inline]
+ pub fn wrapping_shr(self, rhs: u32) -> Self {
+ unsafe {
+ intrinsics::unchecked_shr(self, (rhs & ($BITS - 1)) as $SelfT)
+ }
+ }
}
- /// 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
- ///
- /// ```
- /// use std::u32;
- ///
- /// assert_eq!(5u32.overflowing_sub(2), (3, false));
- /// assert_eq!(0u32.overflowing_sub(1), (u32::MAX, true));
- /// ```
- #[inline]
- #[stable(feature = "wrapping", since = "1.7.0")]
- pub fn overflowing_sub(self, rhs: Self) -> (Self, bool) {
- let (a, b) = unsafe {
- intrinsics::sub_with_overflow(self as $ActualT,
- rhs as $ActualT)
- };
- (a as Self, b)
+ doc_comment! {
+ concat!("Wrapping (modular) exponentiation. Computes `self.pow(exp)`,
+wrapping around at the boundary of the type.
+
+# Examples
+
+Basic usage:
+
+```
+#![feature(no_panic_pow)]
+", $Feature, "assert_eq!(3", stringify!($SelfT), ".wrapping_pow(5), 243);
+assert_eq!(3u8.wrapping_pow(6), 217);", $EndFeature, "
+```"),
+ #[unstable(feature = "no_panic_pow", issue = "48320")]
+ #[inline]
+ pub fn wrapping_pow(self, mut exp: u32) -> Self {
+ let mut base = self;
+ let mut acc: Self = 1;
+
+ while exp > 1 {
+ if (exp & 1) == 1 {
+ acc = acc.wrapping_mul(base);
+ }
+ exp /= 2;
+ base = base.wrapping_mul(base);
+ }
+
+ // Deal with the final bit of the exponent separately, since
+ // squaring the base afterwards is not necessary and may cause a
+ // needless overflow.
+ if exp == 1 {
+ acc = acc.wrapping_mul(base);
+ }
+
+ acc
+ }
+ }
+
+ doc_comment! {
+ concat!("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, "use std::", stringify!($SelfT), ";
+
+assert_eq!(5", stringify!($SelfT), ".overflowing_add(2), (7, false));
+assert_eq!(", stringify!($SelfT), "::MAX.overflowing_add(1), (0, true));", $EndFeature, "
+```"),
+ #[inline]
+ #[stable(feature = "wrapping", since = "1.7.0")]
+ pub fn overflowing_add(self, rhs: Self) -> (Self, bool) {
+ let (a, b) = unsafe {
+ intrinsics::add_with_overflow(self as $ActualT,
+ rhs as $ActualT)
+ };
+ (a as Self, b)
+ }
+ }
+
+ doc_comment! {
+ concat!("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, "use std::", stringify!($SelfT), ";
+
+assert_eq!(5", stringify!($SelfT), ".overflowing_sub(2), (3, false));
+assert_eq!(0", stringify!($SelfT), ".overflowing_sub(1), (", stringify!($SelfT), "::MAX, true));",
+$EndFeature, "
+```"),
+ #[inline]
+ #[stable(feature = "wrapping", since = "1.7.0")]
+ pub fn overflowing_sub(self, rhs: Self) -> (Self, bool) {
+ let (a, b) = unsafe {
+ intrinsics::sub_with_overflow(self as $ActualT,
+ rhs as $ActualT)
+ };
+ (a as Self, b)
+ }
}
/// Calculates the multiplication of `self` and `rhs`.
///
/// # Examples
///
- /// Basic usage
+ /// Basic usage:
+ ///
+ /// Please note that this example is shared between integer types.
+ /// Which explains why `u32` is used here.
///
/// ```
/// assert_eq!(5u32.overflowing_mul(2), (10, false));
(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
- ///
- /// ```
- /// assert_eq!(5u32.overflowing_div(2), (2, false));
- /// ```
- #[inline]
- #[stable(feature = "wrapping", since = "1.7.0")]
- pub fn overflowing_div(self, rhs: Self) -> (Self, bool) {
- (self / rhs, false)
+ doc_comment! {
+ concat!("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, "assert_eq!(5", stringify!($SelfT), ".overflowing_div(2), (2, false));", $EndFeature, "
+```"),
+ #[inline]
+ #[stable(feature = "wrapping", since = "1.7.0")]
+ 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
- ///
- /// ```
- /// assert_eq!(5u32.overflowing_rem(2), (1, false));
- /// ```
- #[inline]
- #[stable(feature = "wrapping", since = "1.7.0")]
- pub fn overflowing_rem(self, rhs: Self) -> (Self, bool) {
- (self % rhs, false)
+ doc_comment! {
+ concat!("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, "assert_eq!(5", stringify!($SelfT), ".overflowing_rem(2), (1, false));", $EndFeature, "
+```"),
+ #[inline]
+ #[stable(feature = "wrapping", since = "1.7.0")]
+ 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
- ///
- /// ```
- /// assert_eq!(0u32.overflowing_neg(), (0, false));
- /// assert_eq!(2u32.overflowing_neg(), (-2i32 as u32, true));
- /// ```
- #[inline]
- #[stable(feature = "wrapping", since = "1.7.0")]
- pub fn overflowing_neg(self) -> (Self, bool) {
- ((!self).wrapping_add(1), self != 0)
+ doc_comment! {
+ concat!("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, "assert_eq!(0", stringify!($SelfT), ".overflowing_neg(), (0, false));
+assert_eq!(2", stringify!($SelfT), ".overflowing_neg(), (-2i32 as ", stringify!($SelfT),
+", true));", $EndFeature, "
+```"),
+ #[inline]
+ #[stable(feature = "wrapping", since = "1.7.0")]
+ 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
- ///
- /// ```
- /// assert_eq!(0x10u32.overflowing_shl(4), (0x100, false));
- /// assert_eq!(0x10u32.overflowing_shl(36), (0x100, true));
- /// ```
- #[inline]
- #[stable(feature = "wrapping", since = "1.7.0")]
- pub fn overflowing_shl(self, rhs: u32) -> (Self, bool) {
- (self.wrapping_shl(rhs), (rhs > ($BITS - 1)))
+ doc_comment! {
+ concat!("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, "assert_eq!(0x1", stringify!($SelfT), ".overflowing_shl(4), (0x10, false));
+assert_eq!(0x1", stringify!($SelfT), ".overflowing_shl(132), (0x10, true));", $EndFeature, "
+```"),
+ #[inline]
+ #[stable(feature = "wrapping", since = "1.7.0")]
+ pub fn overflowing_shl(self, rhs: u32) -> (Self, bool) {
+ (self.wrapping_shl(rhs), (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
- ///
- /// ```
- /// assert_eq!(0x10u32.overflowing_shr(4), (0x1, false));
- /// assert_eq!(0x10u32.overflowing_shr(36), (0x1, true));
- /// ```
- #[inline]
- #[stable(feature = "wrapping", since = "1.7.0")]
- pub fn overflowing_shr(self, rhs: u32) -> (Self, bool) {
- (self.wrapping_shr(rhs), (rhs > ($BITS - 1)))
+ doc_comment! {
+ concat!("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, "assert_eq!(0x10", stringify!($SelfT), ".overflowing_shr(4), (0x1, false));
+assert_eq!(0x10", stringify!($SelfT), ".overflowing_shr(132), (0x1, true));", $EndFeature, "
+```"),
+ #[inline]
+ #[stable(feature = "wrapping", since = "1.7.0")]
+ pub fn overflowing_shr(self, rhs: u32) -> (Self, bool) {
+ (self.wrapping_shr(rhs), (rhs > ($BITS - 1)))
+ }
}
- /// Raises self to the power of `exp`, using exponentiation by squaring.
- ///
- /// # Examples
- ///
- /// Basic usage:
- ///
- /// ```
- /// assert_eq!(2u32.pow(4), 16);
- /// ```
+ doc_comment! {
+ concat!("Raises self to the power of `exp`, using exponentiation by squaring.
+
+Returns a tuple of the exponentiation along with a bool indicating
+whether an overflow happened.
+
+# Examples
+
+Basic usage:
+
+```
+#![feature(no_panic_pow)]
+", $Feature, "assert_eq!(3", stringify!($SelfT), ".overflowing_pow(5), (243, false));
+assert_eq!(3u8.overflowing_pow(6), (217, true));", $EndFeature, "
+```"),
+ #[unstable(feature = "no_panic_pow", issue = "48320")]
+ #[inline]
+ pub fn overflowing_pow(self, mut exp: u32) -> (Self, bool) {
+ let mut base = self;
+ let mut acc: Self = 1;
+ let mut overflown = false;
+ // Scratch space for storing results of overflowing_mul.
+ let mut r;
+
+ while exp > 1 {
+ if (exp & 1) == 1 {
+ r = acc.overflowing_mul(base);
+ acc = r.0;
+ overflown |= r.1;
+ }
+ exp /= 2;
+ r = base.overflowing_mul(base);
+ base = r.0;
+ overflown |= r.1;
+ }
+
+ // Deal with the final bit of the exponent separately, since
+ // squaring the base afterwards is not necessary and may cause a
+ // needless overflow.
+ if exp == 1 {
+ r = acc.overflowing_mul(base);
+ acc = r.0;
+ overflown |= r.1;
+ }
+
+ (acc, overflown)
+ }
+ }
+
+ doc_comment! {
+ concat!("Raises self to the power of `exp`, using exponentiation by squaring.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "assert_eq!(2", stringify!($SelfT), ".pow(5), 32);", $EndFeature, "
+```"),
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
#[rustc_inherit_overflow_checks]
acc
}
+ }
- /// Returns `true` if and only if `self == 2^k` for some `k`.
- ///
- /// # Examples
- ///
- /// Basic usage:
- ///
- /// ```
- /// assert!(16u8.is_power_of_two());
- /// assert!(!10u8.is_power_of_two());
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline]
- pub fn is_power_of_two(self) -> bool {
- (self.wrapping_sub(1)) & self == 0 && !(self == 0)
+ doc_comment! {
+ concat!("Returns `true` if and only if `self == 2^k` for some `k`.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "assert!(16", stringify!($SelfT), ".is_power_of_two());
+assert!(!10", stringify!($SelfT), ".is_power_of_two());", $EndFeature, "
+```"),
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
+ pub fn is_power_of_two(self) -> bool {
+ (self.wrapping_sub(1)) & self == 0 && !(self == 0)
+ }
}
// Returns one less than next power of two.
<$SelfT>::max_value() >> z
}
- /// Returns the smallest power of two greater than or equal to `self`.
- ///
- /// When return value overflows (i.e. `self > (1 << (N-1))` for type
- /// `uN`), it panics in debug mode and return value is wrapped to 0 in
- /// release mode (the only situation in which method can return 0).
- ///
- /// # Examples
- ///
- /// Basic usage:
- ///
- /// ```
- /// assert_eq!(2u8.next_power_of_two(), 2);
- /// assert_eq!(3u8.next_power_of_two(), 4);
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline]
- pub fn next_power_of_two(self) -> Self {
- // Call the trait to get overflow checks
- ops::Add::add(self.one_less_than_next_power_of_two(), 1)
+ doc_comment! {
+ concat!("Returns the smallest power of two greater than or equal to `self`.
+
+When return value overflows (i.e. `self > (1 << (N-1))` for type
+`uN`), it panics in debug mode and return value is wrapped to 0 in
+release mode (the only situation in which method can return 0).
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "assert_eq!(2", stringify!($SelfT), ".next_power_of_two(), 2);
+assert_eq!(3", stringify!($SelfT), ".next_power_of_two(), 4);", $EndFeature, "
+```"),
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
+ pub fn next_power_of_two(self) -> Self {
+ // Call the trait to get overflow checks
+ ops::Add::add(self.one_less_than_next_power_of_two(), 1)
+ }
}
- /// Returns the smallest power of two greater than or equal to `n`. If
- /// the next power of two is greater than the type's maximum value,
- /// `None` is returned, otherwise the power of two is wrapped in `Some`.
- ///
- /// # Examples
- ///
- /// Basic usage:
- ///
- /// ```
- /// assert_eq!(2u8.checked_next_power_of_two(), Some(2));
- /// assert_eq!(3u8.checked_next_power_of_two(), Some(4));
- /// assert_eq!(200u8.checked_next_power_of_two(), None);
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- pub fn checked_next_power_of_two(self) -> Option<Self> {
- self.one_less_than_next_power_of_two().checked_add(1)
+ doc_comment! {
+ concat!("Returns the smallest power of two greater than or equal to `n`. If
+the next power of two is greater than the type's maximum value,
+`None` is returned, otherwise the power of two is wrapped in `Some`.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "assert_eq!(2", stringify!($SelfT),
+".checked_next_power_of_two(), Some(2));
+assert_eq!(3", stringify!($SelfT), ".checked_next_power_of_two(), Some(4));
+assert_eq!(", stringify!($SelfT), "::max_value().checked_next_power_of_two(), None);",
+$EndFeature, "
+```"),
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub fn checked_next_power_of_two(self) -> Option<Self> {
+ self.one_less_than_next_power_of_two().checked_add(1)
+ }
}
}
}
#[lang = "u8"]
impl u8 {
- uint_impl! { u8, u8, 8 }
+ uint_impl! { u8, u8, 8, 255, "", "" }
/// Checks if the value is within the ASCII range.
}
/// Checks if the value is an ASCII graphic character:
- /// U+0021 '@' ... U+007E '~'.
+ /// U+0021 '!' ... U+007E '~'.
///
/// # Examples
///
#[lang = "u16"]
impl u16 {
- uint_impl! { u16, u16, 16 }
+ uint_impl! { u16, u16, 16, 65535, "", "" }
}
#[lang = "u32"]
impl u32 {
- uint_impl! { u32, u32, 32 }
+ uint_impl! { u32, u32, 32, 4294967295, "", "" }
}
#[lang = "u64"]
impl u64 {
- uint_impl! { u64, u64, 64 }
+ uint_impl! { u64, u64, 64, 18446744073709551615, "", "" }
}
#[lang = "u128"]
impl u128 {
- uint_impl! { u128, u128, 128 }
+ uint_impl! { u128, u128, 128, 340282366920938463463374607431768211455, "", "" }
}
#[cfg(target_pointer_width = "16")]
#[lang = "usize"]
impl usize {
- uint_impl! { usize, u16, 16 }
+ uint_impl! { usize, u16, 16, 65536, "", "" }
}
#[cfg(target_pointer_width = "32")]
#[lang = "usize"]
impl usize {
- uint_impl! { usize, u32, 32 }
+ uint_impl! { usize, u32, 32, 4294967295, "", "" }
}
#[cfg(target_pointer_width = "64")]
#[lang = "usize"]
impl usize {
- uint_impl! { usize, u64, 64 }
+ uint_impl! { usize, u64, 64, 18446744073709551615, "", "" }
}
/// A classification of floating point numbers.
issue = "32110")]
pub trait Float: Sized {
/// Type used by `to_bits` and `from_bits`.
- #[stable(feature = "core_float_bits", since = "1.24.0")]
+ #[stable(feature = "core_float_bits", since = "1.25.0")]
type Bits;
/// Returns `true` if this value is NaN and false otherwise.
fn min(self, other: Self) -> Self;
/// Raw transmutation to integer.
- #[stable(feature = "core_float_bits", since="1.24.0")]
+ #[stable(feature = "core_float_bits", since="1.25.0")]
fn to_bits(self) -> Self::Bits;
/// Raw transmutation from integer.
- #[stable(feature = "core_float_bits", since="1.24.0")]
+ #[stable(feature = "core_float_bits", since="1.25.0")]
fn from_bits(v: Self::Bits) -> Self;
}
}
#[unstable(feature = "try_from", issue = "33417")]
-impl From<Infallible> for TryFromIntError {
- fn from(infallible: Infallible) -> TryFromIntError {
- match infallible {
- }
+impl From<!> for TryFromIntError {
+ fn from(never: !) -> TryFromIntError {
+ never
}
}
-// no possible bounds violation
-macro_rules! try_from_unbounded {
- ($source:ty, $($target:ty),*) => {$(
- #[unstable(feature = "try_from", issue = "33417")]
- impl TryFrom<$source> for $target {
- type Error = Infallible;
-
- #[inline]
- fn try_from(value: $source) -> Result<Self, Self::Error> {
- Ok(value as $target)
- }
- }
- )*}
-}
-
// only negative bounds
macro_rules! try_from_lower_bounded {
($source:ty, $($target:ty),*) => {$(
try_from_upper_bounded!(usize, isize);
try_from_lower_bounded!(isize, usize);
+try_from_upper_bounded!(usize, u8);
+try_from_upper_bounded!(usize, i8, i16);
+try_from_both_bounded!(isize, u8);
+try_from_both_bounded!(isize, i8);
+
#[cfg(target_pointer_width = "16")]
mod ptr_try_from_impls {
use super::TryFromIntError;
- use convert::{Infallible, TryFrom};
-
- try_from_upper_bounded!(usize, u8);
- try_from_unbounded!(usize, u16, u32, u64, u128);
- try_from_upper_bounded!(usize, i8, i16);
- try_from_unbounded!(usize, i32, i64, i128);
+ use convert::TryFrom;
- try_from_both_bounded!(isize, u8);
+ // Fallible across platfoms, only implementation differs
try_from_lower_bounded!(isize, u16, u32, u64, u128);
- try_from_both_bounded!(isize, i8);
- try_from_unbounded!(isize, i16, i32, i64, i128);
-
- rev!(try_from_unbounded, usize, u16);
- rev!(try_from_upper_bounded, usize, u32, u64, u128);
rev!(try_from_lower_bounded, usize, i8, i16);
rev!(try_from_both_bounded, usize, i32, i64, i128);
-
- rev!(try_from_unbounded, isize, u8);
- rev!(try_from_upper_bounded, isize, u16, u32, u64, u128);
- rev!(try_from_unbounded, isize, i16);
- rev!(try_from_both_bounded, isize, i32, i64, i128);
}
#[cfg(target_pointer_width = "32")]
mod ptr_try_from_impls {
use super::TryFromIntError;
- use convert::{Infallible, TryFrom};
+ use convert::TryFrom;
- try_from_upper_bounded!(usize, u8, u16);
- try_from_unbounded!(usize, u32, u64, u128);
- try_from_upper_bounded!(usize, i8, i16, i32);
- try_from_unbounded!(usize, i64, i128);
-
- try_from_both_bounded!(isize, u8, u16);
+ // Fallible across platfoms, only implementation differs
+ try_from_both_bounded!(isize, u16);
try_from_lower_bounded!(isize, u32, u64, u128);
- try_from_both_bounded!(isize, i8, i16);
- try_from_unbounded!(isize, i32, i64, i128);
-
- rev!(try_from_unbounded, usize, u16, u32);
- rev!(try_from_upper_bounded, usize, u64, u128);
rev!(try_from_lower_bounded, usize, i8, i16, i32);
rev!(try_from_both_bounded, usize, i64, i128);
-
- rev!(try_from_unbounded, isize, u8, u16);
- rev!(try_from_upper_bounded, isize, u32, u64, u128);
- rev!(try_from_unbounded, isize, i16, i32);
- rev!(try_from_both_bounded, isize, i64, i128);
}
#[cfg(target_pointer_width = "64")]
mod ptr_try_from_impls {
use super::TryFromIntError;
- use convert::{Infallible, TryFrom};
-
- try_from_upper_bounded!(usize, u8, u16, u32);
- try_from_unbounded!(usize, u64, u128);
- try_from_upper_bounded!(usize, i8, i16, i32, i64);
- try_from_unbounded!(usize, i128);
+ use convert::TryFrom;
- try_from_both_bounded!(isize, u8, u16, u32);
+ // Fallible across platfoms, only implementation differs
+ try_from_both_bounded!(isize, u16, u32);
try_from_lower_bounded!(isize, u64, u128);
- try_from_both_bounded!(isize, i8, i16, i32);
- try_from_unbounded!(isize, i64, i128);
-
- rev!(try_from_unbounded, usize, u16, u32, u64);
- rev!(try_from_upper_bounded, usize, u128);
rev!(try_from_lower_bounded, usize, i8, i16, i32, i64);
rev!(try_from_both_bounded, usize, i128);
-
- rev!(try_from_unbounded, isize, u8, u16, u32);
- rev!(try_from_upper_bounded, isize, u64, u128);
- rev!(try_from_unbounded, isize, i16, i32, i64);
- rev!(try_from_both_bounded, isize, i128);
}
#[doc(hidden)]
/// This error is used as the error type for the `from_str_radix()` functions
/// on the primitive integer types, such as [`i8::from_str_radix`].
///
+/// # Potential causes
+///
+/// Among other causes, `ParseIntError` can be thrown because of leading or trailing whitespace
+/// in the string e.g. when it is obtained from the standard input.
+/// Using the [`str.trim()`] method ensures that no whitespace remains before parsing.
+///
+/// [`str.trim()`]: ../../std/primitive.str.html#method.trim
/// [`i8::from_str_radix`]: ../../std/primitive.i8.html#method.from_str_radix
#[derive(Debug, Clone, PartialEq, Eq)]
#[stable(feature = "rust1", since = "1.0.0")]
impl_from! { u8, u16, #[stable(feature = "lossless_int_conv", since = "1.5.0")] }
impl_from! { u8, u32, #[stable(feature = "lossless_int_conv", since = "1.5.0")] }
impl_from! { u8, u64, #[stable(feature = "lossless_int_conv", since = "1.5.0")] }
-impl_from! { u8, u128, #[unstable(feature = "i128", issue = "35118")] }
+impl_from! { u8, u128, #[stable(feature = "i128", since = "1.26.0")] }
impl_from! { u8, usize, #[stable(feature = "lossless_int_conv", since = "1.5.0")] }
impl_from! { u16, u32, #[stable(feature = "lossless_int_conv", since = "1.5.0")] }
impl_from! { u16, u64, #[stable(feature = "lossless_int_conv", since = "1.5.0")] }
-impl_from! { u16, u128, #[unstable(feature = "i128", issue = "35118")] }
+impl_from! { u16, u128, #[stable(feature = "i128", since = "1.26.0")] }
impl_from! { u32, u64, #[stable(feature = "lossless_int_conv", since = "1.5.0")] }
-impl_from! { u32, u128, #[unstable(feature = "i128", issue = "35118")] }
-impl_from! { u64, u128, #[unstable(feature = "i128", issue = "35118")] }
+impl_from! { u32, u128, #[stable(feature = "i128", since = "1.26.0")] }
+impl_from! { u64, u128, #[stable(feature = "i128", since = "1.26.0")] }
// Signed -> Signed
impl_from! { i8, i16, #[stable(feature = "lossless_int_conv", since = "1.5.0")] }
impl_from! { i8, i32, #[stable(feature = "lossless_int_conv", since = "1.5.0")] }
impl_from! { i8, i64, #[stable(feature = "lossless_int_conv", since = "1.5.0")] }
-impl_from! { i8, i128, #[unstable(feature = "i128", issue = "35118")] }
+impl_from! { i8, i128, #[stable(feature = "i128", since = "1.26.0")] }
impl_from! { i8, isize, #[stable(feature = "lossless_int_conv", since = "1.5.0")] }
impl_from! { i16, i32, #[stable(feature = "lossless_int_conv", since = "1.5.0")] }
impl_from! { i16, i64, #[stable(feature = "lossless_int_conv", since = "1.5.0")] }
-impl_from! { i16, i128, #[unstable(feature = "i128", issue = "35118")] }
+impl_from! { i16, i128, #[stable(feature = "i128", since = "1.26.0")] }
impl_from! { i32, i64, #[stable(feature = "lossless_int_conv", since = "1.5.0")] }
-impl_from! { i32, i128, #[unstable(feature = "i128", issue = "35118")] }
-impl_from! { i64, i128, #[unstable(feature = "i128", issue = "35118")] }
+impl_from! { i32, i128, #[stable(feature = "i128", since = "1.26.0")] }
+impl_from! { i64, i128, #[stable(feature = "i128", since = "1.26.0")] }
// Unsigned -> Signed
impl_from! { u8, i16, #[stable(feature = "lossless_int_conv", since = "1.5.0")] }
impl_from! { u8, i32, #[stable(feature = "lossless_int_conv", since = "1.5.0")] }
impl_from! { u8, i64, #[stable(feature = "lossless_int_conv", since = "1.5.0")] }
-impl_from! { u8, i128, #[unstable(feature = "i128", issue = "35118")] }
+impl_from! { u8, i128, #[stable(feature = "i128", since = "1.26.0")] }
impl_from! { u16, i32, #[stable(feature = "lossless_int_conv", since = "1.5.0")] }
impl_from! { u16, i64, #[stable(feature = "lossless_int_conv", since = "1.5.0")] }
-impl_from! { u16, i128, #[unstable(feature = "i128", issue = "35118")] }
+impl_from! { u16, i128, #[stable(feature = "i128", since = "1.26.0")] }
impl_from! { u32, i64, #[stable(feature = "lossless_int_conv", since = "1.5.0")] }
-impl_from! { u32, i128, #[unstable(feature = "i128", issue = "35118")] }
-impl_from! { u64, i128, #[unstable(feature = "i128", issue = "35118")] }
+impl_from! { u32, i128, #[stable(feature = "i128", since = "1.26.0")] }
+impl_from! { u64, i128, #[stable(feature = "i128", since = "1.26.0")] }
+
+// The C99 standard defines bounds on INTPTR_MIN, INTPTR_MAX, and UINTPTR_MAX
+// which imply that pointer-sized integers must be at least 16 bits:
+// https://port70.net/~nsz/c/c99/n1256.html#7.18.2.4
+impl_from! { u16, usize, #[stable(feature = "lossless_iusize_conv", since = "1.26.0")] }
+impl_from! { u8, isize, #[stable(feature = "lossless_iusize_conv", since = "1.26.0")] }
+impl_from! { i16, isize, #[stable(feature = "lossless_iusize_conv", since = "1.26.0")] }
+
+// RISC-V defines the possibility of a 128-bit address space (RV128).
+
+// CHERI proposes 256-bit “capabilities”. Unclear if this would be relevant to usize/isize.
+// https://www.cl.cam.ac.uk/research/security/ctsrd/pdfs/20171017a-cheri-poster.pdf
+// http://www.csl.sri.com/users/neumann/2012resolve-cheri.pdf
+
// Note: integers can only be represented with full precision in a float if
// they fit in the significand, which is 24 bits in f32 and 53 bits in f64.