Return Option from exact_div and inherit overflow checks
This commit is contained in:
parent
402ce0ef07
commit
298d825cbb
4 changed files with 37 additions and 31 deletions
|
|
@ -1019,25 +1019,29 @@ macro_rules! int_impl {
|
|||
}
|
||||
}
|
||||
|
||||
/// Checked integer division without remainder. Computes `self / rhs`.
|
||||
/// Integer division without remainder. Computes `self / rhs`, returning `None` if `self % rhs != 0`.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function will panic if `rhs == 0`, the division results in overflow,
|
||||
/// or `self % rhs != 0`.
|
||||
/// This function will panic if `rhs == 0`.
|
||||
///
|
||||
/// ## Overflow behavior
|
||||
///
|
||||
/// On overflow, this function will panic if overflow checks are enabled (default in debug
|
||||
/// mode) and wrap if overflow checks are disabled (default in release mode).
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(exact_div)]
|
||||
#[doc = concat!("assert_eq!(64", stringify!($SelfT), ".exact_div(2), 32);")]
|
||||
#[doc = concat!("assert_eq!(64", stringify!($SelfT), ".exact_div(32), 2);")]
|
||||
#[doc = concat!("assert_eq!((", stringify!($SelfT), "::MIN + 1).exact_div(-1), ", stringify!($Max), ");")]
|
||||
#[doc = concat!("assert_eq!(64", stringify!($SelfT), ".exact_div(2), Some(32));")]
|
||||
#[doc = concat!("assert_eq!(64", stringify!($SelfT), ".exact_div(32), Some(2));")]
|
||||
#[doc = concat!("assert_eq!((", stringify!($SelfT), "::MIN + 1).exact_div(-1), Some(", stringify!($Max), "));")]
|
||||
#[doc = concat!("assert_eq!(65", stringify!($SelfT), ".exact_div(2), None);")]
|
||||
/// ```
|
||||
///
|
||||
/// ```should_panic
|
||||
/// #![feature(exact_div)]
|
||||
#[doc = concat!("let _ = 65", stringify!($SelfT), ".exact_div(2);")]
|
||||
#[doc = concat!("let _ = 64", stringify!($SelfT),".exact_div(0);")]
|
||||
/// ```
|
||||
/// ```should_panic
|
||||
/// #![feature(exact_div)]
|
||||
|
|
@ -1050,10 +1054,12 @@ macro_rules! int_impl {
|
|||
#[must_use = "this returns the result of the operation, \
|
||||
without modifying the original"]
|
||||
#[inline]
|
||||
pub const fn exact_div(self, rhs: Self) -> Self {
|
||||
match self.checked_exact_div(rhs) {
|
||||
Some(x) => x,
|
||||
None => panic!("Failed to divide without remainder"),
|
||||
#[rustc_inherit_overflow_checks]
|
||||
pub const fn exact_div(self, rhs: Self) -> Option<Self> {
|
||||
if self % rhs != 0 {
|
||||
None
|
||||
} else {
|
||||
Some(self / rhs)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1249,23 +1249,19 @@ macro_rules! uint_impl {
|
|||
}
|
||||
}
|
||||
|
||||
/// Checked integer division without remainder. Computes `self / rhs`.
|
||||
/// Integer division without remainder. Computes `self / rhs`, returning `None` if `self % rhs != 0`.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function will panic if `rhs == 0` or `self % rhs != 0`.
|
||||
/// This function will panic if `rhs == 0`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(exact_div)]
|
||||
#[doc = concat!("assert_eq!(64", stringify!($SelfT), ".exact_div(2), 32);")]
|
||||
#[doc = concat!("assert_eq!(64", stringify!($SelfT), ".exact_div(32), 2);")]
|
||||
/// ```
|
||||
///
|
||||
/// ```should_panic
|
||||
/// #![feature(exact_div)]
|
||||
#[doc = concat!("let _ = 65", stringify!($SelfT), ".exact_div(2);")]
|
||||
#[doc = concat!("assert_eq!(64", stringify!($SelfT), ".exact_div(2), Some(32));")]
|
||||
#[doc = concat!("assert_eq!(64", stringify!($SelfT), ".exact_div(32), Some(2));")]
|
||||
#[doc = concat!("assert_eq!(65", stringify!($SelfT), ".exact_div(2), None);")]
|
||||
/// ```
|
||||
#[unstable(
|
||||
feature = "exact_div",
|
||||
|
|
@ -1274,10 +1270,12 @@ macro_rules! uint_impl {
|
|||
#[must_use = "this returns the result of the operation, \
|
||||
without modifying the original"]
|
||||
#[inline]
|
||||
pub const fn exact_div(self, rhs: Self) -> Self {
|
||||
match self.checked_exact_div(rhs) {
|
||||
Some(x) => x,
|
||||
None => panic!("Failed to divide without remainder"),
|
||||
#[rustc_inherit_overflow_checks]
|
||||
pub const fn exact_div(self, rhs: Self) -> Option<Self> {
|
||||
if self % rhs != 0 {
|
||||
None
|
||||
} else {
|
||||
Some(self / rhs)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -741,22 +741,23 @@ macro_rules! int_module {
|
|||
fn test_exact_div() {
|
||||
// 42 / 6
|
||||
assert_eq_const_safe!(Option<$T>: <$T>::checked_exact_div(EXACT_DIV_SUCCESS_DIVIDEND1, EXACT_DIV_SUCCESS_DIVISOR1), Some(EXACT_DIV_SUCCESS_QUOTIENT1));
|
||||
assert_eq_const_safe!($T: <$T>::exact_div(EXACT_DIV_SUCCESS_DIVIDEND1, EXACT_DIV_SUCCESS_DIVISOR1), EXACT_DIV_SUCCESS_QUOTIENT1);
|
||||
assert_eq_const_safe!(Option<$T>: <$T>::exact_div(EXACT_DIV_SUCCESS_DIVIDEND1, EXACT_DIV_SUCCESS_DIVISOR1), Some(EXACT_DIV_SUCCESS_QUOTIENT1));
|
||||
|
||||
// 18 / 3
|
||||
assert_eq_const_safe!(Option<$T>: <$T>::checked_exact_div(EXACT_DIV_SUCCESS_DIVIDEND2, EXACT_DIV_SUCCESS_DIVISOR2), Some(EXACT_DIV_SUCCESS_QUOTIENT2));
|
||||
assert_eq_const_safe!($T: <$T>::exact_div(EXACT_DIV_SUCCESS_DIVIDEND2, EXACT_DIV_SUCCESS_DIVISOR2), EXACT_DIV_SUCCESS_QUOTIENT2);
|
||||
assert_eq_const_safe!(Option<$T>: <$T>::exact_div(EXACT_DIV_SUCCESS_DIVIDEND2, EXACT_DIV_SUCCESS_DIVISOR2), Some(EXACT_DIV_SUCCESS_QUOTIENT2));
|
||||
|
||||
// -91 / 13
|
||||
assert_eq_const_safe!(Option<$T>: <$T>::checked_exact_div(EXACT_DIV_SUCCESS_DIVIDEND3, EXACT_DIV_SUCCESS_DIVISOR3), Some(EXACT_DIV_SUCCESS_QUOTIENT3));
|
||||
assert_eq_const_safe!($T: <$T>::exact_div(EXACT_DIV_SUCCESS_DIVIDEND3, EXACT_DIV_SUCCESS_DIVISOR3), EXACT_DIV_SUCCESS_QUOTIENT3);
|
||||
assert_eq_const_safe!(Option<$T>: <$T>::exact_div(EXACT_DIV_SUCCESS_DIVIDEND3, EXACT_DIV_SUCCESS_DIVISOR3), Some(EXACT_DIV_SUCCESS_QUOTIENT3));
|
||||
|
||||
// -57 / -3
|
||||
assert_eq_const_safe!(Option<$T>: <$T>::checked_exact_div(EXACT_DIV_SUCCESS_DIVIDEND4, EXACT_DIV_SUCCESS_DIVISOR4), Some(EXACT_DIV_SUCCESS_QUOTIENT4));
|
||||
assert_eq_const_safe!($T: <$T>::exact_div(EXACT_DIV_SUCCESS_DIVIDEND4, EXACT_DIV_SUCCESS_DIVISOR4), EXACT_DIV_SUCCESS_QUOTIENT4);
|
||||
assert_eq_const_safe!(Option<$T>: <$T>::exact_div(EXACT_DIV_SUCCESS_DIVIDEND4, EXACT_DIV_SUCCESS_DIVISOR4), Some(EXACT_DIV_SUCCESS_QUOTIENT4));
|
||||
|
||||
// failures
|
||||
assert_eq_const_safe!(Option<$T>: <$T>::checked_exact_div(1, 2), None);
|
||||
assert_eq_const_safe!(Option<$T>: <$T>::exact_div(1, 2), None);
|
||||
assert_eq_const_safe!(Option<$T>: <$T>::checked_exact_div(<$T>::MIN, -1), None);
|
||||
assert_eq_const_safe!(Option<$T>: <$T>::checked_exact_div(0, 0), None);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -606,14 +606,15 @@ macro_rules! uint_module {
|
|||
fn test_exact_div() {
|
||||
// 42 / 6
|
||||
assert_eq_const_safe!(Option<$T>: <$T>::checked_exact_div(EXACT_DIV_SUCCESS_DIVIDEND1, EXACT_DIV_SUCCESS_DIVISOR1), Some(EXACT_DIV_SUCCESS_QUOTIENT1));
|
||||
assert_eq_const_safe!($T: <$T>::exact_div(EXACT_DIV_SUCCESS_DIVIDEND1, EXACT_DIV_SUCCESS_DIVISOR1), EXACT_DIV_SUCCESS_QUOTIENT1);
|
||||
assert_eq_const_safe!(Option<$T>: <$T>::exact_div(EXACT_DIV_SUCCESS_DIVIDEND1, EXACT_DIV_SUCCESS_DIVISOR1), Some(EXACT_DIV_SUCCESS_QUOTIENT1));
|
||||
|
||||
// 18 / 3
|
||||
assert_eq_const_safe!(Option<$T>: <$T>::checked_exact_div(EXACT_DIV_SUCCESS_DIVIDEND2, EXACT_DIV_SUCCESS_DIVISOR2), Some(EXACT_DIV_SUCCESS_QUOTIENT2));
|
||||
assert_eq_const_safe!($T: <$T>::exact_div(EXACT_DIV_SUCCESS_DIVIDEND2, EXACT_DIV_SUCCESS_DIVISOR2), EXACT_DIV_SUCCESS_QUOTIENT2);
|
||||
assert_eq_const_safe!(Option<$T>: <$T>::exact_div(EXACT_DIV_SUCCESS_DIVIDEND2, EXACT_DIV_SUCCESS_DIVISOR2), Some(EXACT_DIV_SUCCESS_QUOTIENT2));
|
||||
|
||||
// failures
|
||||
assert_eq_const_safe!(Option<$T>: <$T>::checked_exact_div(1, 2), None);
|
||||
assert_eq_const_safe!(Option<$T>: <$T>::exact_div(1, 2), None);
|
||||
assert_eq_const_safe!(Option<$T>: <$T>::checked_exact_div(0, 0), None);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue