diff --git a/library/core/src/num/int_macros.rs b/library/core/src/num/int_macros.rs index 434bcace616f2..dfd717e346aa7 100644 --- a/library/core/src/num/int_macros.rs +++ b/library/core/src/num/int_macros.rs @@ -1085,6 +1085,83 @@ macro_rules! int_impl { if unlikely!(b) { overflow_panic::rem() } else { a } } + /// Checked integer division without remainder. Computes `self / rhs`, + /// returning `None` if `rhs == 0`, the division results in overflow, + /// or remainder is not zero. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// #![feature(norem_div)] + #[doc = concat!("assert_eq!((", stringify!($SelfT), "::MIN + 1).checked_norem_div(-1), Some(", stringify!($Max), "));")] + #[doc = concat!("assert_eq!((-5", stringify!($SelfT), ").checked_norem_div(2), None);")] + #[doc = concat!("assert_eq!(", stringify!($SelfT), "::MIN.checked_norem_div(-1), None);")] + #[doc = concat!("assert_eq!((1", stringify!($SelfT), ").checked_norem_div(0), None);")] + /// ``` + #[unstable( + feature = "norem_div", + issue = "1", + )] + #[must_use = "this returns the result of the operation, \ + without modifying the original"] + #[inline] + pub const fn checked_norem_div(self, rhs: Self) -> Option { + if unlikely!(rhs == 0 || ((self == Self::MIN) && (rhs == -1))) { + None + } else { + // SAFETY: div by zero and by INT_MIN have been checked above + unsafe { + if unlikely!(intrinsics::unchecked_rem(self, rhs) != 0) { + None + } else { + Some(intrinsics::unchecked_div(self, rhs)) + } + } + } + } + + /// Checked integer division without remainder. Computes `self / rhs`. + /// + /// # Panics + /// + /// This function will panic if `rhs == 0`, the division results in overflow, + /// or remainder is not zero. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// #![feature(norem_div)] + #[doc = concat!("assert_eq!(64", stringify!($SelfT), ".norem_div(2), 32);")] + #[doc = concat!("assert_eq!(64", stringify!($SelfT), ".norem_div(32), 2);")] + #[doc = concat!("assert_eq!((", stringify!($SelfT), "::MIN + 1).norem_div(-1), ", stringify!($Max), ");")] + /// ``` + /// + /// ```should_panic + /// #![feature(norem_div)] + #[doc = concat!("let _ = 65", stringify!($SelfT), ".norem_div(2);")] + /// ``` + /// ```should_panic + /// #![feature(norem_div)] + #[doc = concat!("let _ = ", stringify!($SelfT), "::MIN.norem_div(-1);")] + /// ``` + #[unstable( + feature = "norem_div", + issue = "1", + )] + #[must_use = "this returns the result of the operation, \ + without modifying the original"] + #[inline] + pub const fn norem_div(self, rhs: Self) -> Self { + match self.checked_norem_div(rhs) { + Some(v) => v, + None => panic!("Failed to divide without remainder"), + } + } + /// Checked negation. Computes `-self`, returning `None` if `self == MIN`. /// /// # Examples diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs index f2f29e4ad8194..6f3a320ccd6c9 100644 --- a/library/core/src/num/uint_macros.rs +++ b/library/core/src/num/uint_macros.rs @@ -996,6 +996,76 @@ macro_rules! uint_impl { self % rhs } + /// Checked integer division without remainder. Computes `self / rhs`, + /// returning `None` if `rhs == 0` or if division remainder is not zero. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// #![feature(norem_div)] + #[doc = concat!("assert_eq!(128", stringify!($SelfT), ".checked_norem_div(2), Some(64));")] + #[doc = concat!("assert_eq!(129", stringify!($SelfT), ".checked_norem_div(2), None);")] + #[doc = concat!("assert_eq!(1", stringify!($SelfT), ".checked_norem_div(0), None);")] + /// ``` + #[unstable( + feature = "norem_div", + issue = "1", + )] + #[must_use = "this returns the result of the operation, \ + without modifying the original"] + #[inline] + pub const fn checked_norem_div(self, rhs: Self) -> Option { + if unlikely!(rhs == 0) { + None + } else { + // SAFETY: div by zero has been checked above and unsigned types have no other + // failure modes for division + unsafe { + if unlikely!(intrinsics::unchecked_rem(self, rhs) != 0) { + None + } else { + Some(intrinsics::unchecked_div(self, rhs)) + } + } + } + } + + /// Checked integer division without remainder. Computes `self / rhs`. + /// + /// # Panics + /// + /// This function will panic if `rhs == 0` or if division remainder is not zero. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// #![feature(norem_div)] + #[doc = concat!("assert_eq!(128", stringify!($SelfT), ".norem_div(2), 64);")] + #[doc = concat!("assert_eq!(64", stringify!($SelfT), ".norem_div(32), 2);")] + /// ``` + /// + /// ```should_panic + /// #![feature(norem_div)] + #[doc = concat!("let _ = 129", stringify!($SelfT), ".norem_div(2);")] + /// ``` + #[unstable( + feature = "norem_div", + issue = "1", + )] + #[must_use = "this returns the result of the operation, \ + without modifying the original"] + #[inline] + pub const fn norem_div(self, rhs: Self) -> Self { + match self.checked_norem_div(rhs) { + Some(v) => v, + None => panic!("Failed to divide without remainder"), + } + } + /// Returns the logarithm of the number with respect to an arbitrary base, /// rounded down. ///