about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/libcore/num/mod.rs56
-rw-r--r--src/libcore/tests/lib.rs1
-rw-r--r--src/libcore/tests/num/int_macros.rs26
3 files changed, 83 insertions, 0 deletions
diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs
index f1325f383ee..718222ee0f4 100644
--- a/src/libcore/num/mod.rs
+++ b/src/libcore/num/mod.rs
@@ -959,6 +959,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.
 
diff --git a/src/libcore/tests/lib.rs b/src/libcore/tests/lib.rs
index 2e4a8a15d20..a3d294e77d3 100644
--- a/src/libcore/tests/lib.rs
+++ b/src/libcore/tests/lib.rs
@@ -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)]
diff --git a/src/libcore/tests/num/int_macros.rs b/src/libcore/tests/num/int_macros.rs
index 92409465d7f..0475aeb96ab 100644
--- a/src/libcore/tests/num/int_macros.rs
+++ b/src/libcore/tests/num/int_macros.rs
@@ -154,6 +154,32 @@ mod tests {
     }
 
     #[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> {
             ::std::str::FromStr::from_str(t).ok()