about summary refs log tree commit diff
path: root/src/libstd/num
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2013-08-19 12:42:48 -0700
committerbors <bors@rust-lang.org>2013-08-19 12:42:48 -0700
commit4bdceb9c00da0c83e292ca831b25a09235721d2c (patch)
treeac8f7ab2780e1124194fac4b2dfa89e7270cabb9 /src/libstd/num
parent2246d56e7149402f18041d05e3c0ecf598671904 (diff)
parentb244911398c334b02ccf260c557684c4294077ec (diff)
downloadrust-4bdceb9c00da0c83e292ca831b25a09235721d2c.tar.gz
rust-4bdceb9c00da0c83e292ca831b25a09235721d2c.zip
auto merge of #8459 : thestinger/rust/checked, r=graydon
Diffstat (limited to 'src/libstd/num')
-rw-r--r--src/libstd/num/int_macros.rs21
-rw-r--r--src/libstd/num/num.rs4
-rw-r--r--src/libstd/num/uint_macros.rs19
3 files changed, 42 insertions, 2 deletions
diff --git a/src/libstd/num/int_macros.rs b/src/libstd/num/int_macros.rs
index 41da9a6ccbe..0144f926534 100644
--- a/src/libstd/num/int_macros.rs
+++ b/src/libstd/num/int_macros.rs
@@ -17,7 +17,7 @@ macro_rules! int_module (($T:ty, $bits:expr) => (mod generated {
 #[allow(non_uppercase_statics)];
 
 use num::{ToStrRadix, FromStrRadix};
-use num::{Zero, One, strconv};
+use num::{CheckedDiv, Zero, One, strconv};
 use prelude::*;
 use str;
 
@@ -29,6 +29,17 @@ pub static bytes : uint = ($bits / 8);
 pub static min_value: $T = (-1 as $T) << (bits - 1);
 pub static max_value: $T = min_value - 1 as $T;
 
+impl CheckedDiv for $T {
+    #[inline]
+    fn checked_div(&self, v: &$T) -> Option<$T> {
+        if *v == 0 || (*self == min_value && *v == -1) {
+            None
+        } else {
+            Some(self / *v)
+        }
+    }
+}
+
 enum Range { Closed, HalfOpen }
 
 #[inline]
@@ -551,6 +562,7 @@ mod tests {
     use super::*;
     use prelude::*;
 
+    use int;
     use i16;
     use i32;
     use i64;
@@ -921,6 +933,13 @@ mod tests {
     fn test_range_step_zero_step() {
         do range_step(0,10,0) |_i| { true };
     }
+
+    #[test]
+    fn test_signed_checked_div() {
+        assert_eq!(10i.checked_div(&2), Some(5));
+        assert_eq!(5i.checked_div(&0), None);
+        assert_eq!(int::min_value.checked_div(&-1), None);
+    }
 }
 
 }))
diff --git a/src/libstd/num/num.rs b/src/libstd/num/num.rs
index 04a1cc11b26..fbb8913fbfa 100644
--- a/src/libstd/num/num.rs
+++ b/src/libstd/num/num.rs
@@ -892,6 +892,10 @@ impl CheckedMul for uint {
     }
 }
 
+pub trait CheckedDiv: Div<Self, Self> {
+    fn checked_div(&self, v: &Self) -> Option<Self>;
+}
+
 /// Helper function for testing numeric operations
 #[cfg(test)]
 pub fn test_num<T:Num + NumCast>(ten: T, two: T) {
diff --git a/src/libstd/num/uint_macros.rs b/src/libstd/num/uint_macros.rs
index 86b5b4ddfc0..524b035c9f3 100644
--- a/src/libstd/num/uint_macros.rs
+++ b/src/libstd/num/uint_macros.rs
@@ -18,7 +18,7 @@ macro_rules! uint_module (($T:ty, $T_SIGNED:ty, $bits:expr) => (mod generated {
 
 use num::BitCount;
 use num::{ToStrRadix, FromStrRadix};
-use num::{Zero, One, strconv};
+use num::{CheckedDiv, Zero, One, strconv};
 use prelude::*;
 use str;
 
@@ -30,6 +30,17 @@ pub static bytes : uint = ($bits / 8);
 pub static min_value: $T = 0 as $T;
 pub static max_value: $T = 0 as $T - 1 as $T;
 
+impl CheckedDiv for $T {
+    #[inline]
+    fn checked_div(&self, v: &$T) -> Option<$T> {
+        if *v == 0 {
+            None
+        } else {
+            Some(self / *v)
+        }
+    }
+}
+
 enum Range { Closed, HalfOpen }
 
 #[inline]
@@ -694,6 +705,12 @@ mod tests {
     fn test_range_step_zero_step_down() {
         do range_step(0,-10,0) |_i| { true };
     }
+
+    #[test]
+    fn test_unsigned_checked_div() {
+        assert_eq!(10u.checked_div(&2), Some(5));
+        assert_eq!(5u.checked_div(&0), None);
+    }
 }
 
 }))