Skip to content

Commit

Permalink
Make saturating int fns const
Browse files Browse the repository at this point in the history
With rust-lang#49146 merged, these can be const; see rust-lang#53718.
  • Loading branch information
9999years committed Dec 19, 2019
1 parent 17ab2c4 commit e749327
Show file tree
Hide file tree
Showing 2 changed files with 126 additions and 33 deletions.
49 changes: 44 additions & 5 deletions src/libcore/num/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1172,8 +1172,11 @@ $EndFeature, "
```"),

#[unstable(feature = "saturating_neg", issue = "59983")]
#[rustc_const_unstable(feature = "const_saturating_int_methods")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
pub fn saturating_abs(self) -> Self {
pub const fn saturating_abs(self) -> Self {
if self.is_negative() {
self.saturating_neg()
} else {
Expand Down Expand Up @@ -1202,14 +1205,38 @@ $EndFeature, "
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
pub fn saturating_mul(self, rhs: Self) -> Self {
self.checked_mul(rhs).unwrap_or_else(|| {
#[rustc_const_unstable(feature = "const_int_saturating")]
#[cfg(not(bootstrap))]
pub const fn saturating_mul(self, rhs: Self) -> Self {
match self.checked_mul(rhs) {
Some(r) => r,
None => {
if (self < 0) == (rhs < 0) {
Self::max_value()
} else {
Self::min_value()
}
},
}
}
}

/// No docs for bootstrap.
#[stable(feature = "wrapping", since = "1.7.0")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
#[cfg(bootstrap)]
pub fn saturating_mul(self, rhs: Self) -> Self {
match self.checked_mul(rhs) {
Some(r) => r,
None => {
if (self < 0) == (rhs < 0) {
Self::max_value()
} else {
Self::min_value()
}
})
},
}
}

Expand Down Expand Up @@ -3351,11 +3378,23 @@ assert_eq!((", stringify!($SelfT), "::MAX).saturating_mul(10), ", stringify!($Se
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
pub fn saturating_mul(self, rhs: Self) -> Self {
#[rustc_const_unstable(feature = "const_int_saturating")]
#[cfg(not(bootstrap))]
pub const fn saturating_mul(self, rhs: Self) -> Self {
self.checked_mul(rhs).unwrap_or(Self::max_value())
}
}

/// No docs for bootstrap.
#[stable(feature = "wrapping", since = "1.7.0")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
#[cfg(bootstrap)]
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.
Expand Down
110 changes: 82 additions & 28 deletions src/test/ui/consts/const-int-saturating-arith.rs
Original file line number Diff line number Diff line change
@@ -1,34 +1,88 @@
// run-pass
#![feature(const_saturating_int_methods)]
#![feature(const_int_saturating)]
#![feature(saturating_neg)]

const INT_U32_NO: u32 = (42 as u32).saturating_add(2);
const INT_U32: u32 = u32::max_value().saturating_add(1);
const INT_U128: u128 = u128::max_value().saturating_add(1);
const INT_I128: i128 = i128::max_value().saturating_add(1);
const INT_I128_NEG: i128 = i128::min_value().saturating_add(-1);

const INT_U32_NO_SUB: u32 = (42 as u32).saturating_sub(2);
const INT_U32_SUB: u32 = (1 as u32).saturating_sub(2);
const INT_I32_NO_SUB: i32 = (-42 as i32).saturating_sub(2);
const INT_I32_NEG_SUB: i32 = i32::min_value().saturating_sub(1);
const INT_I32_POS_SUB: i32 = i32::max_value().saturating_sub(-1);
const INT_U128_SUB: u128 = (0 as u128).saturating_sub(1);
const INT_I128_NEG_SUB: i128 = i128::min_value().saturating_sub(1);
const INT_I128_POS_SUB: i128 = i128::max_value().saturating_sub(-1);
const ADD_INT_U32_NO: u32 = (42 as u32).saturating_add(2);
const ADD_INT_U32: u32 = u32::max_value().saturating_add(1);
const ADD_INT_U128: u128 = u128::max_value().saturating_add(1);
const ADD_INT_I128: i128 = i128::max_value().saturating_add(1);
const ADD_INT_I128_NEG: i128 = i128::min_value().saturating_add(-1);

const SUB_INT_U32_NO: u32 = (42 as u32).saturating_sub(2);
const SUB_INT_U32: u32 = (1 as u32).saturating_sub(2);
const SUB_INT_I32_NO: i32 = (-42 as i32).saturating_sub(2);
const SUB_INT_I32_NEG: i32 = i32::min_value().saturating_sub(1);
const SUB_INT_I32_POS: i32 = i32::max_value().saturating_sub(-1);
const SUB_INT_U128: u128 = (0 as u128).saturating_sub(1);
const SUB_INT_I128_NEG: i128 = i128::min_value().saturating_sub(1);
const SUB_INT_I128_POS: i128 = i128::max_value().saturating_sub(-1);

const MUL_INT_U32_NO: u32 = (42 as u32).saturating_mul(2);
const MUL_INT_U32: u32 = (1 as u32).saturating_mul(2);
const MUL_INT_I32_NO: i32 = (-42 as i32).saturating_mul(2);
const MUL_INT_I32_NEG: i32 = i32::min_value().saturating_mul(1);
const MUL_INT_I32_POS: i32 = i32::max_value().saturating_mul(2);
const MUL_INT_U128: u128 = (0 as u128).saturating_mul(1);
const MUL_INT_I128_NEG: i128 = i128::min_value().saturating_mul(2);
const MUL_INT_I128_POS: i128 = i128::max_value().saturating_mul(2);

const NEG_INT_I8: i8 = (-42i8).saturating_neg();
const NEG_INT_I8_B: i8 = i8::min_value().saturating_neg();
const NEG_INT_I32: i32 = i32::min_value().saturating_neg();
const NEG_INT_I32_B: i32 = i32::max_value().saturating_neg();
const NEG_INT_I128: i128 = i128::min_value().saturating_neg();
const NEG_INT_I128_B: i128 = i128::max_value().saturating_neg();

const ABS_INT_I8_A: i8 = 4i8.saturating_abs();
const ABS_INT_I8_B: i8 = -4i8.saturating_abs();
const ABS_INT_I8_C: i8 = i8::min_value().saturating_abs();
const ABS_INT_I32_A: i32 = 4i32.saturating_abs();
const ABS_INT_I32_B: i32 = -4i32.saturating_abs();
const ABS_INT_I32_C: i32 = i32::min_value().saturating_abs();
const ABS_INT_I128_A: i128 = 4i128.saturating_abs();
const ABS_INT_I128_B: i128 = -4i128.saturating_abs();
const ABS_INT_I128_C: i128 = i128::min_value().saturating_abs();

fn main() {
assert_eq!(INT_U32_NO, 44);
assert_eq!(INT_U32, u32::max_value());
assert_eq!(INT_U128, u128::max_value());
assert_eq!(INT_I128, i128::max_value());
assert_eq!(INT_I128_NEG, i128::min_value());

assert_eq!(INT_U32_NO_SUB, 40);
assert_eq!(INT_U32_SUB, 0);
assert_eq!(INT_I32_NO_SUB, -44);
assert_eq!(INT_I32_NEG_SUB, i32::min_value());
assert_eq!(INT_I32_POS_SUB, i32::max_value());
assert_eq!(INT_U128_SUB, 0);
assert_eq!(INT_I128_NEG_SUB, i128::min_value());
assert_eq!(INT_I128_POS_SUB, i128::max_value());
assert_eq!(ADD_INT_U32_NO, 44);
assert_eq!(ADD_INT_U32, u32::max_value());
assert_eq!(ADD_INT_U128, u128::max_value());
assert_eq!(ADD_INT_I128, i128::max_value());
assert_eq!(ADD_INT_I128_NEG, i128::min_value());

assert_eq!(SUB_INT_U32_NO, 40);
assert_eq!(SUB_INT_U32, 0);
assert_eq!(SUB_INT_I32_NO, -44);
assert_eq!(SUB_INT_I32_NEG, i32::min_value());
assert_eq!(SUB_INT_I32_POS, i32::max_value());
assert_eq!(SUB_INT_U128, 0);
assert_eq!(SUB_INT_I128_NEG, i128::min_value());
assert_eq!(SUB_INT_I128_POS, i128::max_value());

assert_eq!(MUL_INT_U32_NO, 84);
assert_eq!(MUL_INT_U32, 2);
assert_eq!(MUL_INT_I32_NO, -84);
assert_eq!(MUL_INT_I32_NEG, i32::min_value());
assert_eq!(MUL_INT_I32_POS, i32::max_value());
assert_eq!(MUL_INT_U128, 0);
assert_eq!(MUL_INT_I128_NEG, i128::min_value());
assert_eq!(MUL_INT_I128_POS, i128::max_value());

assert_eq!(NEG_INT_I8, 42);
assert_eq!(NEG_INT_I8_B, i8::max_value());
assert_eq!(NEG_INT_I32, i32::max_value());
assert_eq!(NEG_INT_I32_B, i32::min_value() + 1);
assert_eq!(NEG_INT_I128, i128::max_value());
assert_eq!(NEG_INT_I128_B, i128::min_value() + 1);

assert_eq!(ABS_INT_I8_A, 4i8);
assert_eq!(ABS_INT_I8_B, -4i8);
assert_eq!(ABS_INT_I8_C, i8::max_value());
assert_eq!(ABS_INT_I32_A, 4i32);
assert_eq!(ABS_INT_I32_B, -4i32);
assert_eq!(ABS_INT_I32_C, i32::max_value());
assert_eq!(ABS_INT_I128_A, 4i128);
assert_eq!(ABS_INT_I128_B, -4i128);
assert_eq!(ABS_INT_I128_C, i128::max_value());
}

0 comments on commit e749327

Please sign in to comment.