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 { + fn checked_div(&self, v: &Self) -> Option; +} + /// Helper function for testing numeric operations #[cfg(test)] pub fn test_num(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); + } } }))