]> git.proxmox.com Git - rustc.git/blobdiff - library/core/src/num/uint_macros.rs
New upstream version 1.56.0~beta.4+dfsg1
[rustc.git] / library / core / src / num / uint_macros.rs
index ca1b05fdfbe48a779471995dd7709c9a8baf7d38..e79bf7bd7f3c7f3d8d979927f717ca2f41ef711c 100644 (file)
@@ -15,7 +15,8 @@ macro_rules! uint_impl {
         #[stable(feature = "assoc_int_consts", since = "1.43.0")]
         pub const MIN: Self = 0;
 
-        /// The largest value that can be represented by this integer type.
+        /// The largest value that can be represented by this integer type,
+        #[doc = concat!("2<sup>", $BITS, "</sup> - 1.")]
         ///
         /// # Examples
         ///
@@ -636,7 +637,7 @@ macro_rules! uint_impl {
 
         /// Returns the logarithm of the number with respect to an arbitrary base.
         ///
-        /// This method may not be optimized owing to implementation details;
+        /// This method might not be optimized owing to implementation details;
         /// `log2` can produce results more efficiently for base 2, and `log10`
         /// can produce results more efficiently for base 10.
         ///
@@ -744,7 +745,7 @@ macro_rules! uint_impl {
         ///
         /// Returns `None` if the number is zero, or if the base is not at least 2.
         ///
-        /// This method may not be optimized owing to implementation details;
+        /// This method might not be optimized owing to implementation details;
         /// `checked_log2` can produce results more efficiently for base 2, and
         /// `checked_log10` can produce results more efficiently for base 10.
         ///
@@ -1040,6 +1041,36 @@ macro_rules! uint_impl {
             }
         }
 
+        /// Saturating integer division. Computes `self / rhs`, saturating at the
+        /// numeric bounds instead of overflowing.
+        ///
+        /// # Examples
+        ///
+        /// Basic usage:
+        ///
+        /// ```
+        /// #![feature(saturating_div)]
+        ///
+        #[doc = concat!("assert_eq!(5", stringify!($SelfT), ".saturating_div(2), 2);")]
+        ///
+        /// ```
+        ///
+        /// ```should_panic
+        /// #![feature(saturating_div)]
+        ///
+        #[doc = concat!("let _ = 1", stringify!($SelfT), ".saturating_div(0);")]
+        ///
+        /// ```
+        #[unstable(feature = "saturating_div", issue = "87920")]
+        #[rustc_const_unstable(feature = "saturating_div", issue = "87920")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
+        #[inline]
+        pub const fn saturating_div(self, rhs: Self) -> Self {
+            // on unsigned types, there is no overflow in integer division
+            self.wrapping_div(rhs)
+        }
+
         /// Saturating integer exponentiation. Computes `self.pow(exp)`,
         /// saturating at the numeric bounds instead of overflowing.
         ///
@@ -1245,9 +1276,9 @@ macro_rules! uint_impl {
         /// ```
         #[stable(feature = "num_wrapping", since = "1.2.0")]
         #[rustc_const_stable(feature = "const_wrapping_math", since = "1.32.0")]
-        #[inline]
+        #[inline(always)]
         pub const fn wrapping_neg(self) -> Self {
-            self.overflowing_neg().0
+            (0 as $SelfT).wrapping_sub(self)
         }
 
         /// Panic-free bitwise shift-left; yields `self << mask(rhs)`,
@@ -1377,6 +1408,36 @@ macro_rules! uint_impl {
             (a as Self, b)
         }
 
+        /// Calculates `self + rhs + carry` without the ability to overflow.
+        ///
+        /// Performs "ternary addition" which takes in an extra bit to add, and may return an
+        /// additional bit of overflow. This allows for chaining together multiple additions
+        /// to create "big integers" which represent larger values.
+        ///
+        /// # Examples
+        ///
+        /// Basic usage
+        ///
+        /// ```
+        /// #![feature(bigint_helper_methods)]
+        #[doc = concat!("assert_eq!(5", stringify!($SelfT), ".carrying_add(2, false), (7, false));")]
+        #[doc = concat!("assert_eq!(5", stringify!($SelfT), ".carrying_add(2, true), (8, false));")]
+        #[doc = concat!("assert_eq!(", stringify!($SelfT), "::MAX.carrying_add(1, false), (0, true));")]
+        #[doc = concat!("assert_eq!(", stringify!($SelfT), "::MAX.carrying_add(1, true), (1, true));")]
+        /// ```
+        #[unstable(feature = "bigint_helper_methods", issue = "85532")]
+        #[rustc_const_unstable(feature = "const_bigint_helper_methods", issue = "85532")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
+        #[inline]
+        pub const fn carrying_add(self, rhs: Self, carry: bool) -> (Self, bool) {
+            // note: longer-term this should be done via an intrinsic, but this has been shown
+            //   to generate optimal code for now, and LLVM doesn't have an equivalent intrinsic
+            let (a, b) = self.overflowing_add(rhs);
+            let (c, d) = a.overflowing_add(carry as $SelfT);
+            (c, b | d)
+        }
+
         /// Calculates `self` - `rhs`
         ///
         /// Returns a tuple of the subtraction along with a boolean indicating
@@ -1402,6 +1463,36 @@ macro_rules! uint_impl {
             (a as Self, b)
         }
 
+        /// Calculates `self - rhs - borrow` without the ability to overflow.
+        ///
+        /// Performs "ternary subtraction" which takes in an extra bit to subtract, and may return
+        /// an additional bit of overflow. This allows for chaining together multiple subtractions
+        /// to create "big integers" which represent larger values.
+        ///
+        /// # Examples
+        ///
+        /// Basic usage
+        ///
+        /// ```
+        /// #![feature(bigint_helper_methods)]
+        #[doc = concat!("assert_eq!(5", stringify!($SelfT), ".borrowing_sub(2, false), (3, false));")]
+        #[doc = concat!("assert_eq!(5", stringify!($SelfT), ".borrowing_sub(2, true), (2, false));")]
+        #[doc = concat!("assert_eq!(0", stringify!($SelfT), ".borrowing_sub(1, false), (", stringify!($SelfT), "::MAX, true));")]
+        #[doc = concat!("assert_eq!(0", stringify!($SelfT), ".borrowing_sub(1, true), (", stringify!($SelfT), "::MAX - 1, true));")]
+        /// ```
+        #[unstable(feature = "bigint_helper_methods", issue = "85532")]
+        #[rustc_const_unstable(feature = "const_bigint_helper_methods", issue = "85532")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
+        #[inline]
+        pub const fn borrowing_sub(self, rhs: Self, borrow: bool) -> (Self, bool) {
+            // note: longer-term this should be done via an intrinsic, but this has been shown
+            //   to generate optimal code for now, and LLVM doesn't have an equivalent intrinsic
+            let (a, b) = self.overflowing_sub(rhs);
+            let (c, d) = a.overflowing_sub(borrow as $SelfT);
+            (c, b | d)
+        }
+
         /// Calculates the multiplication of `self` and `rhs`.
         ///
         /// Returns a tuple of the multiplication along with a boolean
@@ -1757,6 +1848,110 @@ macro_rules! uint_impl {
             self % rhs
         }
 
+        /// Calculates the quotient of `self` and `rhs`, rounding the result towards negative infinity.
+        ///
+        /// This is the same as performing `self / rhs` for all unsigned integers.
+        ///
+        /// # Panics
+        ///
+        /// This function will panic if `rhs` is 0.
+        ///
+        /// # Examples
+        ///
+        /// Basic usage:
+        ///
+        /// ```
+        /// #![feature(int_roundings)]
+        #[doc = concat!("assert_eq!(7_", stringify!($SelfT), ".unstable_div_floor(4), 1);")]
+        /// ```
+        #[unstable(feature = "int_roundings", issue = "88581")]
+        #[inline(always)]
+        #[rustc_inherit_overflow_checks]
+        pub const fn unstable_div_floor(self, rhs: Self) -> Self {
+            self / rhs
+        }
+
+        /// Calculates the quotient of `self` and `rhs`, rounding the result towards positive infinity.
+        ///
+        /// # Panics
+        ///
+        /// This function will panic if `rhs` is 0.
+        ///
+        /// # Examples
+        ///
+        /// Basic usage:
+        ///
+        /// ```
+        /// #![feature(int_roundings)]
+        #[doc = concat!("assert_eq!(7_", stringify!($SelfT), ".unstable_div_ceil(4), 2);")]
+        /// ```
+        #[unstable(feature = "int_roundings", issue = "88581")]
+        #[inline]
+        #[rustc_inherit_overflow_checks]
+        pub const fn unstable_div_ceil(self, rhs: Self) -> Self {
+            let d = self / rhs;
+            let r = self % rhs;
+            if r > 0 && rhs > 0 {
+                d + 1
+            } else {
+                d
+            }
+        }
+
+        /// Calculates the smallest value greater than or equal to `self` that
+        /// is a multiple of `rhs`.
+        ///
+        /// # Panics
+        ///
+        /// This function will panic if `rhs` is 0 or the operation results in overflow.
+        ///
+        /// # Examples
+        ///
+        /// Basic usage:
+        ///
+        /// ```
+        /// #![feature(int_roundings)]
+        #[doc = concat!("assert_eq!(16_", stringify!($SelfT), ".unstable_next_multiple_of(8), 16);")]
+        #[doc = concat!("assert_eq!(23_", stringify!($SelfT), ".unstable_next_multiple_of(8), 24);")]
+        /// ```
+        #[unstable(feature = "int_roundings", issue = "88581")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
+        #[inline]
+        #[rustc_inherit_overflow_checks]
+        pub const fn unstable_next_multiple_of(self, rhs: Self) -> Self {
+            match self % rhs {
+                0 => self,
+                r => self + (rhs - r)
+            }
+        }
+
+        /// Calculates the smallest value greater than or equal to `self` that
+        /// is a multiple of `rhs`. If `rhs` is negative,
+        ///
+        /// # Examples
+        ///
+        /// Basic usage:
+        ///
+        /// ```
+        /// #![feature(int_roundings)]
+        #[doc = concat!("assert_eq!(16_", stringify!($SelfT), ".checked_next_multiple_of(8), Some(16));")]
+        #[doc = concat!("assert_eq!(23_", stringify!($SelfT), ".checked_next_multiple_of(8), Some(24));")]
+        #[doc = concat!("assert_eq!(1_", stringify!($SelfT), ".checked_next_multiple_of(0), None);")]
+        #[doc = concat!("assert_eq!(", stringify!($SelfT), "::MAX.checked_next_multiple_of(2), None);")]
+        /// ```
+        #[unstable(feature = "int_roundings", issue = "88581")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
+        #[inline]
+        #[rustc_inherit_overflow_checks]
+        pub const fn checked_next_multiple_of(self, rhs: Self) -> Option<Self> {
+            match try_opt!(self.checked_rem(rhs)) {
+                0 => Some(self),
+                r => self.checked_add(try_opt!(rhs.checked_sub(r)))
+            }
+        }
+
         /// Returns `true` if and only if `self == 2^k` for some `k`.
         ///
         /// # Examples
@@ -1926,7 +2121,7 @@ macro_rules! uint_impl {
         #[rustc_const_stable(feature = "const_int_conversion", since = "1.44.0")]
         // SAFETY: const sound because integers are plain old datatypes so we can always
         // transmute them to arrays of bytes
-        #[rustc_allow_const_fn_unstable(const_fn_transmute)]
+        #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_fn_transmute))]
         #[inline]
         pub const fn to_ne_bytes(self) -> [u8; mem::size_of::<Self>()] {
             // SAFETY: integers are plain old datatypes so we can always transmute them to
@@ -2032,7 +2227,7 @@ macro_rules! uint_impl {
         #[rustc_const_stable(feature = "const_int_conversion", since = "1.44.0")]
         // SAFETY: const sound because integers are plain old datatypes so we can always
         // transmute to them
-        #[rustc_allow_const_fn_unstable(const_fn_transmute)]
+        #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_fn_transmute))]
         #[inline]
         pub const fn from_ne_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
             // SAFETY: integers are plain old datatypes so we can always transmute to them