Auto merge of #60192 - t-rapp:tr-saturating-funcs, r=alexcrichton
Implement saturating_abs() and saturating_neg() functions for signed integer types Similar to wrapping_abs() / wrapping_neg() functions but saturating at the numeric bounds instead of wrapping around. Complements the existing set of functions with saturation mechanics. cc #59983
This commit is contained in:
@@ -958,6 +958,62 @@ $EndFeature, "
|
||||
}
|
||||
}
|
||||
|
||||
doc_comment! {
|
||||
concat!("Saturating integer negation. Computes `-self`, returning `MAX` if `self == MIN`
|
||||
instead of overflowing.
|
||||
|
||||
# Examples
|
||||
|
||||
Basic usage:
|
||||
|
||||
```
|
||||
", $Feature, "#![feature(saturating_neg)]
|
||||
assert_eq!(100", stringify!($SelfT), ".saturating_neg(), -100);
|
||||
assert_eq!((-100", stringify!($SelfT), ").saturating_neg(), 100);
|
||||
assert_eq!(", stringify!($SelfT), "::min_value().saturating_neg(), ", stringify!($SelfT),
|
||||
"::max_value());
|
||||
assert_eq!(", stringify!($SelfT), "::max_value().saturating_neg(), ", stringify!($SelfT),
|
||||
"::min_value() + 1);",
|
||||
$EndFeature, "
|
||||
```"),
|
||||
|
||||
#[unstable(feature = "saturating_neg", issue = "59983")]
|
||||
#[inline]
|
||||
pub fn saturating_neg(self) -> Self {
|
||||
intrinsics::saturating_sub(0, self)
|
||||
}
|
||||
}
|
||||
|
||||
doc_comment! {
|
||||
concat!("Saturating absolute value. Computes `self.abs()`, returning `MAX` if `self ==
|
||||
MIN` instead of overflowing.
|
||||
|
||||
# Examples
|
||||
|
||||
Basic usage:
|
||||
|
||||
```
|
||||
", $Feature, "#![feature(saturating_neg)]
|
||||
assert_eq!(100", stringify!($SelfT), ".saturating_abs(), 100);
|
||||
assert_eq!((-100", stringify!($SelfT), ").saturating_abs(), 100);
|
||||
assert_eq!(", stringify!($SelfT), "::min_value().saturating_abs(), ", stringify!($SelfT),
|
||||
"::max_value());
|
||||
assert_eq!((", stringify!($SelfT), "::min_value() + 1).saturating_abs(), ", stringify!($SelfT),
|
||||
"::max_value());",
|
||||
$EndFeature, "
|
||||
```"),
|
||||
|
||||
#[unstable(feature = "saturating_neg", issue = "59983")]
|
||||
#[inline]
|
||||
pub fn saturating_abs(self) -> Self {
|
||||
if self.is_negative() {
|
||||
self.saturating_neg()
|
||||
} else {
|
||||
self
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
doc_comment! {
|
||||
concat!("Saturating integer multiplication. Computes `self * rhs`, saturating at the
|
||||
numeric bounds instead of overflowing.
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#![feature(pattern)]
|
||||
#![feature(range_is_empty)]
|
||||
#![feature(raw)]
|
||||
#![feature(saturating_neg)]
|
||||
#![feature(slice_patterns)]
|
||||
#![feature(sort_internals)]
|
||||
#![feature(slice_partition_at_index)]
|
||||
|
||||
@@ -153,6 +153,32 @@ mod tests {
|
||||
assert_eq!(isize::MIN.checked_div(-1), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_saturating_abs() {
|
||||
assert_eq!((0 as $T).saturating_abs(), 0);
|
||||
assert_eq!((123 as $T).saturating_abs(), 123);
|
||||
assert_eq!((-123 as $T).saturating_abs(), 123);
|
||||
assert_eq!((MAX - 2).saturating_abs(), MAX - 2);
|
||||
assert_eq!((MAX - 1).saturating_abs(), MAX - 1);
|
||||
assert_eq!(MAX.saturating_abs(), MAX);
|
||||
assert_eq!((MIN + 2).saturating_abs(), MAX - 1);
|
||||
assert_eq!((MIN + 1).saturating_abs(), MAX);
|
||||
assert_eq!(MIN.saturating_abs(), MAX);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_saturating_neg() {
|
||||
assert_eq!((0 as $T).saturating_neg(), 0);
|
||||
assert_eq!((123 as $T).saturating_neg(), -123);
|
||||
assert_eq!((-123 as $T).saturating_neg(), 123);
|
||||
assert_eq!((MAX - 2).saturating_neg(), MIN + 3);
|
||||
assert_eq!((MAX - 1).saturating_neg(), MIN + 2);
|
||||
assert_eq!(MAX.saturating_neg(), MIN + 1);
|
||||
assert_eq!((MIN + 2).saturating_neg(), MAX - 1);
|
||||
assert_eq!((MIN + 1).saturating_neg(), MAX);
|
||||
assert_eq!(MIN.saturating_neg(), MAX);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_from_str() {
|
||||
fn from_str<T: ::std::str::FromStr>(t: &str) -> Option<T> {
|
||||
|
||||
Reference in New Issue
Block a user