diff options
| author | Brendan Zabarauskas <bjzaba@yahoo.com.au> | 2014-11-10 00:11:28 +1100 |
|---|---|---|
| committer | Brendan Zabarauskas <bjzaba@yahoo.com.au> | 2014-11-13 02:02:44 +1100 |
| commit | e51cc089da7f5a067d348ee48f494c5bca662f95 (patch) | |
| tree | 999f0ab2a748880de52b1d5d18b51b9151ceaeab /src/libstd | |
| parent | 7e57cd843ccf303d1387ced8d331cb1c19cdaf1c (diff) | |
| download | rust-e51cc089da7f5a067d348ee48f494c5bca662f95.tar.gz rust-e51cc089da7f5a067d348ee48f494c5bca662f95.zip | |
Move checked arithmetic operators into Int trait
Diffstat (limited to 'src/libstd')
| -rw-r--r-- | src/libstd/collections/hash/table.rs | 8 | ||||
| -rw-r--r-- | src/libstd/num/mod.rs | 43 | ||||
| -rw-r--r-- | src/libstd/num/strconv.rs | 8 | ||||
| -rw-r--r-- | src/libstd/prelude.rs | 2 | ||||
| -rw-r--r-- | src/libstd/time/duration.rs | 131 |
5 files changed, 90 insertions, 102 deletions
diff --git a/src/libstd/collections/hash/table.rs b/src/libstd/collections/hash/table.rs index b39b15b3eb9..dd65a00d110 100644 --- a/src/libstd/collections/hash/table.rs +++ b/src/libstd/collections/hash/table.rs @@ -17,7 +17,7 @@ use iter::{Iterator, count}; use kinds::{Sized, marker}; use mem::{min_align_of, size_of}; use mem; -use num::{CheckedAdd, CheckedMul, UnsignedInt}; +use num::{Int, UnsignedInt}; use ops::{Deref, DerefMut, Drop}; use option::{Some, None, Option}; use ptr::{RawPtr, copy_nonoverlapping_memory, zero_memory}; @@ -604,9 +604,9 @@ impl<K, V> RawTable<K, V> { vals_size, min_align_of::< V >()); // One check for overflow that covers calculation and rounding of size. - let size_of_bucket = size_of::<u64>().checked_add(&size_of::<K>()).unwrap() - .checked_add(&size_of::<V>()).unwrap(); - assert!(size >= capacity.checked_mul(&size_of_bucket) + let size_of_bucket = size_of::<u64>().checked_add(size_of::<K>()).unwrap() + .checked_add(size_of::<V>()).unwrap(); + assert!(size >= capacity.checked_mul(size_of_bucket) .expect("capacity overflow"), "capacity overflow"); diff --git a/src/libstd/num/mod.rs b/src/libstd/num/mod.rs index fefde35ea21..2be88e01eed 100644 --- a/src/libstd/num/mod.rs +++ b/src/libstd/num/mod.rs @@ -24,7 +24,6 @@ pub use core::num::{Num, div_rem, Zero, zero, One, one}; pub use core::num::{Signed, abs, signum}; pub use core::num::{Unsigned, pow, Bounded}; pub use core::num::{Primitive, Int, UnsignedInt}; -pub use core::num::{CheckedAdd, CheckedSub, CheckedMul, CheckedDiv}; pub use core::num::{cast, FromPrimitive, NumCast, ToPrimitive}; pub use core::num::{next_power_of_two, is_power_of_two}; pub use core::num::{checked_next_power_of_two}; @@ -636,36 +635,36 @@ mod tests { #[test] fn test_checked_add() { let five_less = uint::MAX - 5; - assert_eq!(five_less.checked_add(&0), Some(uint::MAX - 5)); - assert_eq!(five_less.checked_add(&1), Some(uint::MAX - 4)); - assert_eq!(five_less.checked_add(&2), Some(uint::MAX - 3)); - assert_eq!(five_less.checked_add(&3), Some(uint::MAX - 2)); - assert_eq!(five_less.checked_add(&4), Some(uint::MAX - 1)); - assert_eq!(five_less.checked_add(&5), Some(uint::MAX)); - assert_eq!(five_less.checked_add(&6), None); - assert_eq!(five_less.checked_add(&7), None); + assert_eq!(five_less.checked_add(0), Some(uint::MAX - 5)); + assert_eq!(five_less.checked_add(1), Some(uint::MAX - 4)); + assert_eq!(five_less.checked_add(2), Some(uint::MAX - 3)); + assert_eq!(five_less.checked_add(3), Some(uint::MAX - 2)); + assert_eq!(five_less.checked_add(4), Some(uint::MAX - 1)); + assert_eq!(five_less.checked_add(5), Some(uint::MAX)); + assert_eq!(five_less.checked_add(6), None); + assert_eq!(five_less.checked_add(7), None); } #[test] fn test_checked_sub() { - assert_eq!(5u.checked_sub(&0), Some(5)); - assert_eq!(5u.checked_sub(&1), Some(4)); - assert_eq!(5u.checked_sub(&2), Some(3)); - assert_eq!(5u.checked_sub(&3), Some(2)); - assert_eq!(5u.checked_sub(&4), Some(1)); - assert_eq!(5u.checked_sub(&5), Some(0)); - assert_eq!(5u.checked_sub(&6), None); - assert_eq!(5u.checked_sub(&7), None); + assert_eq!(5u.checked_sub(0), Some(5)); + assert_eq!(5u.checked_sub(1), Some(4)); + assert_eq!(5u.checked_sub(2), Some(3)); + assert_eq!(5u.checked_sub(3), Some(2)); + assert_eq!(5u.checked_sub(4), Some(1)); + assert_eq!(5u.checked_sub(5), Some(0)); + assert_eq!(5u.checked_sub(6), None); + assert_eq!(5u.checked_sub(7), None); } #[test] fn test_checked_mul() { let third = uint::MAX / 3; - assert_eq!(third.checked_mul(&0), Some(0)); - assert_eq!(third.checked_mul(&1), Some(third)); - assert_eq!(third.checked_mul(&2), Some(third * 2)); - assert_eq!(third.checked_mul(&3), Some(third * 3)); - assert_eq!(third.checked_mul(&4), None); + assert_eq!(third.checked_mul(0), Some(0)); + assert_eq!(third.checked_mul(1), Some(third)); + assert_eq!(third.checked_mul(2), Some(third * 2)); + assert_eq!(third.checked_mul(3), Some(third * 3)); + assert_eq!(third.checked_mul(4), None); } macro_rules! test_next_power_of_two( diff --git a/src/libstd/num/strconv.rs b/src/libstd/num/strconv.rs index 088ea89818e..875d03d6c25 100644 --- a/src/libstd/num/strconv.rs +++ b/src/libstd/num/strconv.rs @@ -601,11 +601,11 @@ pub fn from_str_radix_int<T: Int>(src: &str, radix: uint) -> Option<T> { Some(x) => x, None => return None, }; - result = match result.checked_mul(&radix) { + result = match result.checked_mul(radix) { Some(result) => result, None => return None, }; - result = match result.checked_add(&x) { + result = match result.checked_add(x) { Some(result) => result, None => return None, }; @@ -616,11 +616,11 @@ pub fn from_str_radix_int<T: Int>(src: &str, radix: uint) -> Option<T> { Some(x) => x, None => return None, }; - result = match result.checked_mul(&radix) { + result = match result.checked_mul(radix) { Some(result) => result, None => return None, }; - result = match result.checked_sub(&x) { + result = match result.checked_sub(x) { Some(result) => result, None => return None, }; diff --git a/src/libstd/prelude.rs b/src/libstd/prelude.rs index f1090e75127..3c20d205b77 100644 --- a/src/libstd/prelude.rs +++ b/src/libstd/prelude.rs @@ -67,7 +67,7 @@ #[doc(no_inline)] pub use iter::{Iterator, DoubleEndedIterator}; #[doc(no_inline)] pub use iter::{RandomAccessIterator, CloneableIterator}; #[doc(no_inline)] pub use iter::{OrdIterator, MutableDoubleEndedIterator}; -#[doc(no_inline)] pub use num::{Num, NumCast, CheckedAdd, CheckedSub, CheckedMul, CheckedDiv}; +#[doc(no_inline)] pub use num::{Num, NumCast}; #[doc(no_inline)] pub use num::{Signed, Unsigned, Primitive, Int, Float}; #[doc(no_inline)] pub use num::{FloatMath, ToPrimitive, FromPrimitive}; #[doc(no_inline)] pub use boxed::Box; diff --git a/src/libstd/time/duration.rs b/src/libstd/time/duration.rs index c3adae8cff8..6afeb76b83f 100644 --- a/src/libstd/time/duration.rs +++ b/src/libstd/time/duration.rs @@ -15,8 +15,7 @@ use {fmt, i64}; use ops::{Add, Sub, Mul, Div, Neg}; use option::{Option, Some, None}; -use num; -use num::{CheckedAdd, CheckedMul}; +use num::Int; use result::{Result, Ok, Err}; /// The number of nanoseconds in a microsecond. @@ -69,7 +68,7 @@ impl Duration { /// Fails when the duration is out of bounds. #[inline] pub fn weeks(weeks: i64) -> Duration { - let secs = weeks.checked_mul(&SECS_PER_WEEK).expect("Duration::weeks out of bounds"); + let secs = weeks.checked_mul(SECS_PER_WEEK).expect("Duration::weeks out of bounds"); Duration::seconds(secs) } @@ -78,7 +77,7 @@ impl Duration { /// Fails when the duration is out of bounds. #[inline] pub fn days(days: i64) -> Duration { - let secs = days.checked_mul(&SECS_PER_DAY).expect("Duration::days out of bounds"); + let secs = days.checked_mul(SECS_PER_DAY).expect("Duration::days out of bounds"); Duration::seconds(secs) } @@ -87,7 +86,7 @@ impl Duration { /// Fails when the duration is out of bounds. #[inline] pub fn hours(hours: i64) -> Duration { - let secs = hours.checked_mul(&SECS_PER_HOUR).expect("Duration::hours ouf of bounds"); + let secs = hours.checked_mul(SECS_PER_HOUR).expect("Duration::hours ouf of bounds"); Duration::seconds(secs) } @@ -96,7 +95,7 @@ impl Duration { /// Fails when the duration is out of bounds. #[inline] pub fn minutes(minutes: i64) -> Duration { - let secs = minutes.checked_mul(&SECS_PER_MINUTE).expect("Duration::minutes out of bounds"); + let secs = minutes.checked_mul(SECS_PER_MINUTE).expect("Duration::minutes out of bounds"); Duration::seconds(secs) } @@ -191,33 +190,64 @@ impl Duration { /// Returns the total number of whole microseconds in the duration, /// or `None` on overflow (exceeding 2^63 microseconds in either direction). pub fn num_microseconds(&self) -> Option<i64> { - let secs_part = try_opt!(self.num_seconds().checked_mul(&MICROS_PER_SEC)); + let secs_part = try_opt!(self.num_seconds().checked_mul(MICROS_PER_SEC)); let nanos_part = self.nanos_mod_sec() / NANOS_PER_MICRO; - secs_part.checked_add(&(nanos_part as i64)) + secs_part.checked_add(nanos_part as i64) } /// Returns the total number of whole nanoseconds in the duration, /// or `None` on overflow (exceeding 2^63 nanoseconds in either direction). pub fn num_nanoseconds(&self) -> Option<i64> { - let secs_part = try_opt!(self.num_seconds().checked_mul(&(NANOS_PER_SEC as i64))); + let secs_part = try_opt!(self.num_seconds().checked_mul(NANOS_PER_SEC as i64)); let nanos_part = self.nanos_mod_sec(); - secs_part.checked_add(&(nanos_part as i64)) + secs_part.checked_add(nanos_part as i64) } -} -impl num::Bounded for Duration { - #[inline] fn min_value() -> Duration { MIN } - #[inline] fn max_value() -> Duration { MAX } -} + /// Add two durations, returning `None` if overflow occured. + pub fn checked_add(&self, rhs: &Duration) -> Option<Duration> { + let mut secs = try_opt!(self.secs.checked_add(rhs.secs)); + let mut nanos = self.nanos + rhs.nanos; + if nanos >= NANOS_PER_SEC { + nanos -= NANOS_PER_SEC; + secs = try_opt!(secs.checked_add(1)); + } + let d = Duration { secs: secs, nanos: nanos }; + // Even if d is within the bounds of i64 seconds, + // it might still overflow i64 milliseconds. + if d < MIN || d > MAX { None } else { Some(d) } + } + + /// Subtract two durations, returning `None` if overflow occured. + pub fn checked_sub(&self, rhs: &Duration) -> Option<Duration> { + let mut secs = try_opt!(self.secs.checked_sub(rhs.secs)); + let mut nanos = self.nanos - rhs.nanos; + if nanos < 0 { + nanos += NANOS_PER_SEC; + secs = try_opt!(secs.checked_sub(1)); + } + let d = Duration { secs: secs, nanos: nanos }; + // Even if d is within the bounds of i64 seconds, + // it might still overflow i64 milliseconds. + if d < MIN || d > MAX { None } else { Some(d) } + } -impl num::Zero for Duration { + /// The minimum possible `Duration`: `i64::MIN` milliseconds. #[inline] - fn zero() -> Duration { + pub fn min_value() -> Duration { MIN } + + /// The maximum possible `Duration`: `i64::MAX` milliseconds. + #[inline] + pub fn max_value() -> Duration { MAX } + + /// A duration where the stored seconds and nanoseconds are equal to zero. + #[inline] + pub fn zero() -> Duration { Duration { secs: 0, nanos: 0 } } + /// Returns `true` if the duration equals `Duration::zero()`. #[inline] - fn is_zero(&self) -> bool { + pub fn is_zero(&self) -> bool { self.secs == 0 && self.nanos == 0 } } @@ -245,21 +275,6 @@ impl Add<Duration,Duration> for Duration { } } -impl num::CheckedAdd for Duration { - fn checked_add(&self, rhs: &Duration) -> Option<Duration> { - let mut secs = try_opt!(self.secs.checked_add(&rhs.secs)); - let mut nanos = self.nanos + rhs.nanos; - if nanos >= NANOS_PER_SEC { - nanos -= NANOS_PER_SEC; - secs = try_opt!(secs.checked_add(&1)); - } - let d = Duration { secs: secs, nanos: nanos }; - // Even if d is within the bounds of i64 seconds, - // it might still overflow i64 milliseconds. - if d < MIN || d > MAX { None } else { Some(d) } - } -} - impl Sub<Duration,Duration> for Duration { fn sub(&self, rhs: &Duration) -> Duration { let mut secs = self.secs - rhs.secs; @@ -272,21 +287,6 @@ impl Sub<Duration,Duration> for Duration { } } -impl num::CheckedSub for Duration { - fn checked_sub(&self, rhs: &Duration) -> Option<Duration> { - let mut secs = try_opt!(self.secs.checked_sub(&rhs.secs)); - let mut nanos = self.nanos - rhs.nanos; - if nanos < 0 { - nanos += NANOS_PER_SEC; - secs = try_opt!(secs.checked_sub(&1)); - } - let d = Duration { secs: secs, nanos: nanos }; - // Even if d is within the bounds of i64 seconds, - // it might still overflow i64 milliseconds. - if d < MIN || d > MAX { None } else { Some(d) } - } -} - impl Mul<i32,Duration> for Duration { fn mul(&self, rhs: &i32) -> Duration { // Multiply nanoseconds as i64, because it cannot overflow that way. @@ -379,15 +379,12 @@ fn div_rem_64(this: i64, other: i64) -> (i64, i64) { mod tests { use super::{Duration, MIN, MAX}; use {i32, i64}; - use num::{Zero, CheckedAdd, CheckedSub}; use option::{Some, None}; use to_string::ToString; #[test] fn test_duration() { - let d: Duration = Zero::zero(); - assert_eq!(d, Zero::zero()); - assert!(Duration::seconds(1) != Zero::zero()); + assert!(Duration::seconds(1) != Duration::zero()); assert_eq!(Duration::seconds(1) + Duration::seconds(2), Duration::seconds(3)); assert_eq!(Duration::seconds(86399) + Duration::seconds(4), Duration::days(1) + Duration::seconds(3)); @@ -403,8 +400,7 @@ mod tests { #[test] fn test_duration_num_days() { - let d: Duration = Zero::zero(); - assert_eq!(d.num_days(), 0); + assert_eq!(Duration::zero().num_days(), 0); assert_eq!(Duration::days(1).num_days(), 1); assert_eq!(Duration::days(-1).num_days(), -1); assert_eq!(Duration::seconds(86399).num_days(), 0); @@ -417,8 +413,7 @@ mod tests { #[test] fn test_duration_num_seconds() { - let d: Duration = Zero::zero(); - assert_eq!(d.num_seconds(), 0); + assert_eq!(Duration::zero().num_seconds(), 0); assert_eq!(Duration::seconds(1).num_seconds(), 1); assert_eq!(Duration::seconds(-1).num_seconds(), -1); assert_eq!(Duration::milliseconds(999).num_seconds(), 0); @@ -429,8 +424,7 @@ mod tests { #[test] fn test_duration_num_milliseconds() { - let d: Duration = Zero::zero(); - assert_eq!(d.num_milliseconds(), 0); + assert_eq!(Duration::zero().num_milliseconds(), 0); assert_eq!(Duration::milliseconds(1).num_milliseconds(), 1); assert_eq!(Duration::milliseconds(-1).num_milliseconds(), -1); assert_eq!(Duration::microseconds(999).num_milliseconds(), 0); @@ -445,8 +439,7 @@ mod tests { #[test] fn test_duration_num_microseconds() { - let d: Duration = Zero::zero(); - assert_eq!(d.num_microseconds(), Some(0)); + assert_eq!(Duration::zero().num_microseconds(), Some(0)); assert_eq!(Duration::microseconds(1).num_microseconds(), Some(1)); assert_eq!(Duration::microseconds(-1).num_microseconds(), Some(-1)); assert_eq!(Duration::nanoseconds(999).num_microseconds(), Some(0)); @@ -470,8 +463,7 @@ mod tests { #[test] fn test_duration_num_nanoseconds() { - let d: Duration = Zero::zero(); - assert_eq!(d.num_nanoseconds(), Some(0)); + assert_eq!(Duration::zero().num_nanoseconds(), Some(0)); assert_eq!(Duration::nanoseconds(1).num_nanoseconds(), Some(1)); assert_eq!(Duration::nanoseconds(-1).num_nanoseconds(), Some(-1)); assert_eq!(Duration::nanoseconds(i64::MAX).num_nanoseconds(), Some(i64::MAX)); @@ -504,10 +496,9 @@ mod tests { #[test] fn test_duration_mul() { - let d: Duration = Zero::zero(); - assert_eq!(d * i32::MAX, d); - assert_eq!(d * i32::MIN, d); - assert_eq!(Duration::nanoseconds(1) * 0, Zero::zero()); + assert_eq!(Duration::zero() * i32::MAX, Duration::zero()); + assert_eq!(Duration::zero() * i32::MIN, Duration::zero()); + assert_eq!(Duration::nanoseconds(1) * 0, Duration::zero()); assert_eq!(Duration::nanoseconds(1) * 1, Duration::nanoseconds(1)); assert_eq!(Duration::nanoseconds(1) * 1_000_000_000, Duration::seconds(1)); assert_eq!(Duration::nanoseconds(1) * -1_000_000_000, -Duration::seconds(1)); @@ -522,9 +513,8 @@ mod tests { #[test] fn test_duration_div() { - let d: Duration = Zero::zero(); - assert_eq!(d / i32::MAX, d); - assert_eq!(d / i32::MIN, d); + assert_eq!(Duration::zero() / i32::MAX, Duration::zero()); + assert_eq!(Duration::zero() / i32::MIN, Duration::zero()); assert_eq!(Duration::nanoseconds(123_456_789) / 1, Duration::nanoseconds(123_456_789)); assert_eq!(Duration::nanoseconds(123_456_789) / -1, -Duration::nanoseconds(123_456_789)); assert_eq!(-Duration::nanoseconds(123_456_789) / -1, Duration::nanoseconds(123_456_789)); @@ -540,8 +530,7 @@ mod tests { #[test] fn test_duration_fmt() { - let d: Duration = Zero::zero(); - assert_eq!(d.to_string(), "PT0S".to_string()); + assert_eq!(Duration::zero().to_string(), "PT0S".to_string()); assert_eq!(Duration::days(42).to_string(), "P42D".to_string()); assert_eq!(Duration::days(-42).to_string(), "-P42D".to_string()); assert_eq!(Duration::seconds(42).to_string(), "PT42S".to_string()); |
