Skip to content

Commit c32171b

Browse files
committed
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
2 parents bd31c39 + c7d47c8 commit c32171b

File tree

3 files changed

+83
-0
lines changed

3 files changed

+83
-0
lines changed

src/libcore/num/mod.rs

+56
Original file line numberDiff line numberDiff line change
@@ -958,6 +958,62 @@ $EndFeature, "
958958
}
959959
}
960960

961+
doc_comment! {
962+
concat!("Saturating integer negation. Computes `-self`, returning `MAX` if `self == MIN`
963+
instead of overflowing.
964+
965+
# Examples
966+
967+
Basic usage:
968+
969+
```
970+
", $Feature, "#![feature(saturating_neg)]
971+
assert_eq!(100", stringify!($SelfT), ".saturating_neg(), -100);
972+
assert_eq!((-100", stringify!($SelfT), ").saturating_neg(), 100);
973+
assert_eq!(", stringify!($SelfT), "::min_value().saturating_neg(), ", stringify!($SelfT),
974+
"::max_value());
975+
assert_eq!(", stringify!($SelfT), "::max_value().saturating_neg(), ", stringify!($SelfT),
976+
"::min_value() + 1);",
977+
$EndFeature, "
978+
```"),
979+
980+
#[unstable(feature = "saturating_neg", issue = "59983")]
981+
#[inline]
982+
pub fn saturating_neg(self) -> Self {
983+
intrinsics::saturating_sub(0, self)
984+
}
985+
}
986+
987+
doc_comment! {
988+
concat!("Saturating absolute value. Computes `self.abs()`, returning `MAX` if `self ==
989+
MIN` instead of overflowing.
990+
991+
# Examples
992+
993+
Basic usage:
994+
995+
```
996+
", $Feature, "#![feature(saturating_neg)]
997+
assert_eq!(100", stringify!($SelfT), ".saturating_abs(), 100);
998+
assert_eq!((-100", stringify!($SelfT), ").saturating_abs(), 100);
999+
assert_eq!(", stringify!($SelfT), "::min_value().saturating_abs(), ", stringify!($SelfT),
1000+
"::max_value());
1001+
assert_eq!((", stringify!($SelfT), "::min_value() + 1).saturating_abs(), ", stringify!($SelfT),
1002+
"::max_value());",
1003+
$EndFeature, "
1004+
```"),
1005+
1006+
#[unstable(feature = "saturating_neg", issue = "59983")]
1007+
#[inline]
1008+
pub fn saturating_abs(self) -> Self {
1009+
if self.is_negative() {
1010+
self.saturating_neg()
1011+
} else {
1012+
self
1013+
}
1014+
}
1015+
}
1016+
9611017
doc_comment! {
9621018
concat!("Saturating integer multiplication. Computes `self * rhs`, saturating at the
9631019
numeric bounds instead of overflowing.

src/libcore/tests/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#![feature(pattern)]
1717
#![feature(range_is_empty)]
1818
#![feature(raw)]
19+
#![feature(saturating_neg)]
1920
#![feature(slice_patterns)]
2021
#![feature(sort_internals)]
2122
#![feature(slice_partition_at_index)]

src/libcore/tests/num/int_macros.rs

+26
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,32 @@ mod tests {
153153
assert_eq!(isize::MIN.checked_div(-1), None);
154154
}
155155

156+
#[test]
157+
fn test_saturating_abs() {
158+
assert_eq!((0 as $T).saturating_abs(), 0);
159+
assert_eq!((123 as $T).saturating_abs(), 123);
160+
assert_eq!((-123 as $T).saturating_abs(), 123);
161+
assert_eq!((MAX - 2).saturating_abs(), MAX - 2);
162+
assert_eq!((MAX - 1).saturating_abs(), MAX - 1);
163+
assert_eq!(MAX.saturating_abs(), MAX);
164+
assert_eq!((MIN + 2).saturating_abs(), MAX - 1);
165+
assert_eq!((MIN + 1).saturating_abs(), MAX);
166+
assert_eq!(MIN.saturating_abs(), MAX);
167+
}
168+
169+
#[test]
170+
fn test_saturating_neg() {
171+
assert_eq!((0 as $T).saturating_neg(), 0);
172+
assert_eq!((123 as $T).saturating_neg(), -123);
173+
assert_eq!((-123 as $T).saturating_neg(), 123);
174+
assert_eq!((MAX - 2).saturating_neg(), MIN + 3);
175+
assert_eq!((MAX - 1).saturating_neg(), MIN + 2);
176+
assert_eq!(MAX.saturating_neg(), MIN + 1);
177+
assert_eq!((MIN + 2).saturating_neg(), MAX - 1);
178+
assert_eq!((MIN + 1).saturating_neg(), MAX);
179+
assert_eq!(MIN.saturating_neg(), MAX);
180+
}
181+
156182
#[test]
157183
fn test_from_str() {
158184
fn from_str<T: ::std::str::FromStr>(t: &str) -> Option<T> {

0 commit comments

Comments
 (0)