diff options
| author | Alex Crichton <alex@alexcrichton.com> | 2014-04-30 22:23:26 -0700 |
|---|---|---|
| committer | Alex Crichton <alex@alexcrichton.com> | 2014-05-07 08:15:58 -0700 |
| commit | be0a11729e5226a758261ba4f095978ef2105837 (patch) | |
| tree | 12a0f2df31415c7f6aa507d6c08c77466aa8ed54 /src | |
| parent | 0c302938866cbccdecdcd78b42bb46106fdfa28e (diff) | |
| download | rust-be0a11729e5226a758261ba4f095978ef2105837.tar.gz rust-be0a11729e5226a758261ba4f095978ef2105837.zip | |
core: Inherit the specific numeric modules
This implements all traits inside of core::num for all the primitive types, removing all the functionality from libstd. The std modules reexport all of the necessary items from the core modules.
Diffstat (limited to 'src')
30 files changed, 1825 insertions, 1506 deletions
diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index fbc38fa1e5c..ec19a312713 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -21,6 +21,25 @@ #![feature(globs, macro_rules, managed_boxes)] #![deny(missing_doc)] +#[path = "num/float_macros.rs"] mod float_macros; +#[path = "num/int_macros.rs"] mod int_macros; +#[path = "num/uint_macros.rs"] mod uint_macros; + +#[path = "num/int.rs"] pub mod int; +#[path = "num/i8.rs"] pub mod i8; +#[path = "num/i16.rs"] pub mod i16; +#[path = "num/i32.rs"] pub mod i32; +#[path = "num/i64.rs"] pub mod i64; + +#[path = "num/uint.rs"] pub mod uint; +#[path = "num/u8.rs"] pub mod u8; +#[path = "num/u16.rs"] pub mod u16; +#[path = "num/u32.rs"] pub mod u32; +#[path = "num/u64.rs"] pub mod u64; + +#[path = "num/f32.rs"] pub mod f32; +#[path = "num/f64.rs"] pub mod f64; + pub mod num; /* Core modules for ownership management */ diff --git a/src/libcore/num/f32.rs b/src/libcore/num/f32.rs new file mode 100644 index 00000000000..ac45f52e710 --- /dev/null +++ b/src/libcore/num/f32.rs @@ -0,0 +1,224 @@ +// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! Operations and constants for 32-bits floats (`f32` type) + +use cmp::{Eq, Ord}; +use default::Default; +use intrinsics; +use num::{Zero, One, Bounded, Signed, Num, Primitive}; +use ops::{Add, Sub, Mul, Div, Rem, Neg}; + +pub static RADIX: uint = 2u; + +pub static MANTISSA_DIGITS: uint = 24u; +pub static DIGITS: uint = 6u; + +pub static EPSILON: f32 = 1.19209290e-07_f32; + +/// Smallest finite f32 value +pub static MIN_VALUE: f32 = -3.40282347e+38_f32; +/// Smallest positive, normalized f32 value +pub static MIN_POS_VALUE: f32 = 1.17549435e-38_f32; +/// Largest finite f32 value +pub static MAX_VALUE: f32 = 3.40282347e+38_f32; + +pub static MIN_EXP: int = -125; +pub static MAX_EXP: int = 128; + +pub static MIN_10_EXP: int = -37; +pub static MAX_10_EXP: int = 38; + +pub static NAN: f32 = 0.0_f32/0.0_f32; +pub static INFINITY: f32 = 1.0_f32/0.0_f32; +pub static NEG_INFINITY: f32 = -1.0_f32/0.0_f32; + +/// Various useful constants. +pub mod consts { + // FIXME: replace with mathematical constants from cmath. + + // FIXME(#5527): These constants should be deprecated once associated + // constants are implemented in favour of referencing the respective members + // of `Float`. + + /// Archimedes' constant + pub static PI: f32 = 3.14159265358979323846264338327950288_f32; + + /// pi * 2.0 + pub static PI_2: f32 = 6.28318530717958647692528676655900576_f32; + + /// pi/2.0 + pub static FRAC_PI_2: f32 = 1.57079632679489661923132169163975144_f32; + + /// pi/3.0 + pub static FRAC_PI_3: f32 = 1.04719755119659774615421446109316763_f32; + + /// pi/4.0 + pub static FRAC_PI_4: f32 = 0.785398163397448309615660845819875721_f32; + + /// pi/6.0 + pub static FRAC_PI_6: f32 = 0.52359877559829887307710723054658381_f32; + + /// pi/8.0 + pub static FRAC_PI_8: f32 = 0.39269908169872415480783042290993786_f32; + + /// 1.0/pi + pub static FRAC_1_PI: f32 = 0.318309886183790671537767526745028724_f32; + + /// 2.0/pi + pub static FRAC_2_PI: f32 = 0.636619772367581343075535053490057448_f32; + + /// 2.0/sqrt(pi) + pub static FRAC_2_SQRTPI: f32 = 1.12837916709551257389615890312154517_f32; + + /// sqrt(2.0) + pub static SQRT2: f32 = 1.41421356237309504880168872420969808_f32; + + /// 1.0/sqrt(2.0) + pub static FRAC_1_SQRT2: f32 = 0.707106781186547524400844362104849039_f32; + + /// Euler's number + pub static E: f32 = 2.71828182845904523536028747135266250_f32; + + /// log2(e) + pub static LOG2_E: f32 = 1.44269504088896340735992468100189214_f32; + + /// log10(e) + pub static LOG10_E: f32 = 0.434294481903251827651128918916605082_f32; + + /// ln(2.0) + pub static LN_2: f32 = 0.693147180559945309417232121458176568_f32; + + /// ln(10.0) + pub static LN_10: f32 = 2.30258509299404568401799145468436421_f32; +} + +impl Ord for f32 { + #[inline] + fn lt(&self, other: &f32) -> bool { (*self) < (*other) } + #[inline] + fn le(&self, other: &f32) -> bool { (*self) <= (*other) } + #[inline] + fn ge(&self, other: &f32) -> bool { (*self) >= (*other) } + #[inline] + fn gt(&self, other: &f32) -> bool { (*self) > (*other) } +} +impl Eq for f32 { + #[inline] + fn eq(&self, other: &f32) -> bool { (*self) == (*other) } +} + +impl Num for f32 {} + +impl Default for f32 { + #[inline] + fn default() -> f32 { 0.0 } +} + +impl Primitive for f32 {} + +impl Zero for f32 { + #[inline] + fn zero() -> f32 { 0.0 } + + /// Returns true if the number is equal to either `0.0` or `-0.0` + #[inline] + fn is_zero(&self) -> bool { *self == 0.0 || *self == -0.0 } +} + +impl One for f32 { + #[inline] + fn one() -> f32 { 1.0 } +} + +#[cfg(not(test))] +impl Add<f32,f32> for f32 { + #[inline] + fn add(&self, other: &f32) -> f32 { *self + *other } +} + +#[cfg(not(test))] +impl Sub<f32,f32> for f32 { + #[inline] + fn sub(&self, other: &f32) -> f32 { *self - *other } +} + +#[cfg(not(test))] +impl Mul<f32,f32> for f32 { + #[inline] + fn mul(&self, other: &f32) -> f32 { *self * *other } +} + +#[cfg(not(test))] +impl Div<f32,f32> for f32 { + #[inline] + fn div(&self, other: &f32) -> f32 { *self / *other } +} + +#[cfg(not(test))] +impl Rem<f32,f32> for f32 { + #[inline] + fn rem(&self, other: &f32) -> f32 { + extern { fn fmodf(a: f32, b: f32) -> f32; } + unsafe { fmodf(*self, *other) } + } +} + +#[cfg(not(test))] +impl Neg<f32> for f32 { + #[inline] + fn neg(&self) -> f32 { -*self } +} + +impl Signed for f32 { + /// Computes the absolute value. Returns `NAN` if the number is `NAN`. + #[inline] + fn abs(&self) -> f32 { + unsafe { intrinsics::fabsf32(*self) } + } + + /// The positive difference of two numbers. Returns `0.0` if the number is + /// less than or equal to `other`, otherwise the difference between`self` + /// and `other` is returned. + #[inline] + fn abs_sub(&self, other: &f32) -> f32 { + extern { fn fdimf(a: f32, b: f32) -> f32; } + unsafe { fdimf(*self, *other) } + } + + /// # Returns + /// + /// - `1.0` if the number is positive, `+0.0` or `INFINITY` + /// - `-1.0` if the number is negative, `-0.0` or `NEG_INFINITY` + /// - `NAN` if the number is NaN + #[inline] + fn signum(&self) -> f32 { + if self != self { NAN } else { + unsafe { intrinsics::copysignf32(1.0, *self) } + } + } + + /// Returns `true` if the number is positive, including `+0.0` and `INFINITY` + #[inline] + fn is_positive(&self) -> bool { *self > 0.0 || (1.0 / *self) == INFINITY } + + /// Returns `true` if the number is negative, including `-0.0` and `NEG_INFINITY` + #[inline] + fn is_negative(&self) -> bool { *self < 0.0 || (1.0 / *self) == NEG_INFINITY } +} + +impl Bounded for f32 { + // NOTE: this is the smallest non-infinite f32 value, *not* MIN_VALUE + #[inline] + fn min_value() -> f32 { -MAX_VALUE } + + #[inline] + fn max_value() -> f32 { MAX_VALUE } +} diff --git a/src/libcore/num/f64.rs b/src/libcore/num/f64.rs new file mode 100644 index 00000000000..f83ab510b7f --- /dev/null +++ b/src/libcore/num/f64.rs @@ -0,0 +1,224 @@ +// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! Operations and constants for 64-bits floats (`f64` type) + +use cmp::{Eq, Ord}; +use default::Default; +use intrinsics; +use num::{Zero, One, Bounded, Signed, Num, Primitive}; +use ops::{Add, Sub, Mul, Div, Rem, Neg}; + +// FIXME(#5527): These constants should be deprecated once associated +// constants are implemented in favour of referencing the respective +// members of `Bounded` and `Float`. + +pub static RADIX: uint = 2u; + +pub static MANTISSA_DIGITS: uint = 53u; +pub static DIGITS: uint = 15u; + +pub static EPSILON: f64 = 2.2204460492503131e-16_f64; + +/// Smallest finite f64 value +pub static MIN_VALUE: f64 = -1.7976931348623157e+308_f64; +/// Smallest positive, normalized f64 value +pub static MIN_POS_VALUE: f64 = 2.2250738585072014e-308_f64; +/// Largest finite f64 value +pub static MAX_VALUE: f64 = 1.7976931348623157e+308_f64; + +pub static MIN_EXP: int = -1021; +pub static MAX_EXP: int = 1024; + +pub static MIN_10_EXP: int = -307; +pub static MAX_10_EXP: int = 308; + +pub static NAN: f64 = 0.0_f64/0.0_f64; + +pub static INFINITY: f64 = 1.0_f64/0.0_f64; + +pub static NEG_INFINITY: f64 = -1.0_f64/0.0_f64; + +/// Various useful constants. +pub mod consts { + // FIXME: replace with mathematical constants from cmath. + + // FIXME(#5527): These constants should be deprecated once associated + // constants are implemented in favour of referencing the respective members + // of `Float`. + + /// Archimedes' constant + pub static PI: f64 = 3.14159265358979323846264338327950288_f64; + + /// pi * 2.0 + pub static PI_2: f64 = 6.28318530717958647692528676655900576_f64; + + /// pi/2.0 + pub static FRAC_PI_2: f64 = 1.57079632679489661923132169163975144_f64; + + /// pi/3.0 + pub static FRAC_PI_3: f64 = 1.04719755119659774615421446109316763_f64; + + /// pi/4.0 + pub static FRAC_PI_4: f64 = 0.785398163397448309615660845819875721_f64; + + /// pi/6.0 + pub static FRAC_PI_6: f64 = 0.52359877559829887307710723054658381_f64; + + /// pi/8.0 + pub static FRAC_PI_8: f64 = 0.39269908169872415480783042290993786_f64; + + /// 1.0/pi + pub static FRAC_1_PI: f64 = 0.318309886183790671537767526745028724_f64; + + /// 2.0/pi + pub static FRAC_2_PI: f64 = 0.636619772367581343075535053490057448_f64; + + /// 2.0/sqrt(pi) + pub static FRAC_2_SQRTPI: f64 = 1.12837916709551257389615890312154517_f64; + + /// sqrt(2.0) + pub static SQRT2: f64 = 1.41421356237309504880168872420969808_f64; + + /// 1.0/sqrt(2.0) + pub static FRAC_1_SQRT2: f64 = 0.707106781186547524400844362104849039_f64; + + /// Euler's number + pub static E: f64 = 2.71828182845904523536028747135266250_f64; + + /// log2(e) + pub static LOG2_E: f64 = 1.44269504088896340735992468100189214_f64; + + /// log10(e) + pub static LOG10_E: f64 = 0.434294481903251827651128918916605082_f64; + + /// ln(2.0) + pub static LN_2: f64 = 0.693147180559945309417232121458176568_f64; + + /// ln(10.0) + pub static LN_10: f64 = 2.30258509299404568401799145468436421_f64; +} + +impl Ord for f64 { + #[inline] + fn lt(&self, other: &f64) -> bool { (*self) < (*other) } + #[inline] + fn le(&self, other: &f64) -> bool { (*self) <= (*other) } + #[inline] + fn ge(&self, other: &f64) -> bool { (*self) >= (*other) } + #[inline] + fn gt(&self, other: &f64) -> bool { (*self) > (*other) } +} +impl Eq for f64 { + #[inline] + fn eq(&self, other: &f64) -> bool { (*self) == (*other) } +} + +impl Default for f64 { + #[inline] + fn default() -> f64 { 0.0 } +} + +impl Primitive for f64 {} + +impl Num for f64 {} + +impl Zero for f64 { + #[inline] + fn zero() -> f64 { 0.0 } + + /// Returns true if the number is equal to either `0.0` or `-0.0` + #[inline] + fn is_zero(&self) -> bool { *self == 0.0 || *self == -0.0 } +} + +impl One for f64 { + #[inline] + fn one() -> f64 { 1.0 } +} + +#[cfg(not(test))] +impl Add<f64,f64> for f64 { + #[inline] + fn add(&self, other: &f64) -> f64 { *self + *other } +} +#[cfg(not(test))] +impl Sub<f64,f64> for f64 { + #[inline] + fn sub(&self, other: &f64) -> f64 { *self - *other } +} +#[cfg(not(test))] +impl Mul<f64,f64> for f64 { + #[inline] + fn mul(&self, other: &f64) -> f64 { *self * *other } +} +#[cfg(not(test))] +impl Div<f64,f64> for f64 { + #[inline] + fn div(&self, other: &f64) -> f64 { *self / *other } +} +#[cfg(not(test))] +impl Rem<f64,f64> for f64 { + #[inline] + fn rem(&self, other: &f64) -> f64 { + extern { fn fmod(a: f64, b: f64) -> f64; } + unsafe { fmod(*self, *other) } + } +} +#[cfg(not(test))] +impl Neg<f64> for f64 { + #[inline] + fn neg(&self) -> f64 { -*self } +} + +impl Signed for f64 { + /// Computes the absolute value. Returns `NAN` if the number is `NAN`. + #[inline] + fn abs(&self) -> f64 { + unsafe { intrinsics::fabsf64(*self) } + } + + /// The positive difference of two numbers. Returns `0.0` if the number is less than or + /// equal to `other`, otherwise the difference between`self` and `other` is returned. + #[inline] + fn abs_sub(&self, other: &f64) -> f64 { + extern { fn fdim(a: f64, b: f64) -> f64; } + unsafe { fdim(*self, *other) } + } + + /// # Returns + /// + /// - `1.0` if the number is positive, `+0.0` or `INFINITY` + /// - `-1.0` if the number is negative, `-0.0` or `NEG_INFINITY` + /// - `NAN` if the number is NaN + #[inline] + fn signum(&self) -> f64 { + if self != self { NAN } else { + unsafe { intrinsics::copysignf64(1.0, *self) } + } + } + + /// Returns `true` if the number is positive, including `+0.0` and `INFINITY` + #[inline] + fn is_positive(&self) -> bool { *self > 0.0 || (1.0 / *self) == INFINITY } + + /// Returns `true` if the number is negative, including `-0.0` and `NEG_INFINITY` + #[inline] + fn is_negative(&self) -> bool { *self < 0.0 || (1.0 / *self) == NEG_INFINITY } +} + +impl Bounded for f64 { + // NOTE: this is the smallest non-infinite f32 value, *not* MIN_VALUE + #[inline] + fn min_value() -> f64 { -MAX_VALUE } + + #[inline] + fn max_value() -> f64 { MAX_VALUE } +} diff --git a/src/libcore/num/float_macros.rs b/src/libcore/num/float_macros.rs new file mode 100644 index 00000000000..3e403219a4f --- /dev/null +++ b/src/libcore/num/float_macros.rs @@ -0,0 +1,20 @@ +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![macro_escape] +#![doc(hidden)] + +macro_rules! assert_approx_eq( + ($a:expr, $b:expr) => ({ + let (a, b) = (&$a, &$b); + assert!((*a - *b).abs() < 1.0e-6, + "{} is not approximately equal to {}", *a, *b); + }) +) diff --git a/src/libcore/num/i16.rs b/src/libcore/num/i16.rs new file mode 100644 index 00000000000..63ad3bf7d90 --- /dev/null +++ b/src/libcore/num/i16.rs @@ -0,0 +1,68 @@ +// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! Operations and constants for signed 16-bits integers (`i16` type) + +use cmp::{Eq, Ord, TotalEq, TotalOrd, Less, Greater, Equal, Ordering}; +use default::Default; +use intrinsics; +use num::{Bitwise, Bounded, Zero, One, Signed, Num, Primitive, Int}; +use num::{CheckedDiv, CheckedAdd, CheckedSub, CheckedMul}; +use ops::{Add, Sub, Mul, Div, Rem, Neg, BitOr, BitAnd, BitXor}; +use ops::{Shl, Shr, Not}; +use option::{Option, Some, None}; + +int_module!(i16, 16) + +impl Bitwise for i16 { + /// Returns the number of ones in the binary representation of the number. + #[inline] + fn count_ones(&self) -> i16 { unsafe { intrinsics::ctpop16(*self as u16) as i16 } } + + /// Returns the number of leading zeros in the in the binary representation + /// of the number. + #[inline] + fn leading_zeros(&self) -> i16 { unsafe { intrinsics::ctlz16(*self as u16) as i16 } } + + /// Returns the number of trailing zeros in the in the binary representation + /// of the number. + #[inline] + fn trailing_zeros(&self) -> i16 { unsafe { intrinsics::cttz16(*self as u16) as i16 } } +} + +impl CheckedAdd for i16 { + #[inline] + fn checked_add(&self, v: &i16) -> Option<i16> { + unsafe { + let (x, y) = intrinsics::i16_add_with_overflow(*self, *v); + if y { None } else { Some(x) } + } + } +} + +impl CheckedSub for i16 { + #[inline] + fn checked_sub(&self, v: &i16) -> Option<i16> { + unsafe { + let (x, y) = intrinsics::i16_sub_with_overflow(*self, *v); + if y { None } else { Some(x) } + } + } +} + +impl CheckedMul for i16 { + #[inline] + fn checked_mul(&self, v: &i16) -> Option<i16> { + unsafe { + let (x, y) = intrinsics::i16_mul_with_overflow(*self, *v); + if y { None } else { Some(x) } + } + } +} diff --git a/src/libcore/num/i32.rs b/src/libcore/num/i32.rs new file mode 100644 index 00000000000..25f11be459e --- /dev/null +++ b/src/libcore/num/i32.rs @@ -0,0 +1,68 @@ +// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! Operations and constants for signed 32-bits integers (`i32` type) + +use cmp::{Eq, Ord, TotalEq, TotalOrd, Less, Greater, Equal, Ordering}; +use default::Default; +use intrinsics; +use num::{Bitwise, Bounded, Zero, One, Signed, Num, Primitive, Int}; +use num::{CheckedDiv, CheckedAdd, CheckedSub, CheckedMul}; +use ops::{Add, Sub, Mul, Div, Rem, Neg, BitOr, BitAnd, BitXor}; +use ops::{Shl, Shr, Not}; +use option::{Option, Some, None}; + +int_module!(i32, 32) + +impl Bitwise for i32 { + /// Returns the number of ones in the binary representation of the number. + #[inline] + fn count_ones(&self) -> i32 { unsafe { intrinsics::ctpop32(*self as u32) as i32 } } + + /// Returns the number of leading zeros in the in the binary representation + /// of the number. + #[inline] + fn leading_zeros(&self) -> i32 { unsafe { intrinsics::ctlz32(*self as u32) as i32 } } + + /// Returns the number of trailing zeros in the in the binary representation + /// of the number. + #[inline] + fn trailing_zeros(&self) -> i32 { unsafe { intrinsics::cttz32(*self as u32) as i32 } } +} + +impl CheckedAdd for i32 { + #[inline] + fn checked_add(&self, v: &i32) -> Option<i32> { + unsafe { + let (x, y) = intrinsics::i32_add_with_overflow(*self, *v); + if y { None } else { Some(x) } + } + } +} + +impl CheckedSub for i32 { + #[inline] + fn checked_sub(&self, v: &i32) -> Option<i32> { + unsafe { + let (x, y) = intrinsics::i32_sub_with_overflow(*self, *v); + if y { None } else { Some(x) } + } + } +} + +impl CheckedMul for i32 { + #[inline] + fn checked_mul(&self, v: &i32) -> Option<i32> { + unsafe { + let (x, y) = intrinsics::i32_mul_with_overflow(*self, *v); + if y { None } else { Some(x) } + } + } +} diff --git a/src/libcore/num/i64.rs b/src/libcore/num/i64.rs new file mode 100644 index 00000000000..24585009a1b --- /dev/null +++ b/src/libcore/num/i64.rs @@ -0,0 +1,67 @@ +// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! Operations and constants for signed 64-bits integers (`i64` type) + +use cmp::{Eq, Ord, TotalEq, TotalOrd, Less, Greater, Equal, Ordering}; +use default::Default; +use intrinsics; +use num::{Bitwise, Bounded, Zero, One, Signed, Num, Primitive, Int}; +use num::{CheckedDiv, CheckedAdd, CheckedSub, CheckedMul}; +use ops::{Add, Sub, Mul, Div, Rem, Neg, BitOr, BitAnd, BitXor}; +use ops::{Shl, Shr, Not}; +use option::{Option, Some, None}; + +int_module!(i64, 64) + +impl Bitwise for i64 { + /// Returns the number of ones in the binary representation of the number. + #[inline] + fn count_ones(&self) -> i64 { unsafe { intrinsics::ctpop64(*self as u64) as i64 } } + + /// Returns the number of leading zeros in the in the binary representation + /// of the number. + #[inline] + fn leading_zeros(&self) -> i64 { unsafe { intrinsics::ctlz64(*self as u64) as i64 } } + + /// Counts the number of trailing zeros. + #[inline] + fn trailing_zeros(&self) -> i64 { unsafe { intrinsics::cttz64(*self as u64) as i64 } } +} + +impl CheckedAdd for i64 { + #[inline] + fn checked_add(&self, v: &i64) -> Option<i64> { + unsafe { + let (x, y) = intrinsics::i64_add_with_overflow(*self, *v); + if y { None } else { Some(x) } + } + } +} + +impl CheckedSub for i64 { + #[inline] + fn checked_sub(&self, v: &i64) -> Option<i64> { + unsafe { + let (x, y) = intrinsics::i64_sub_with_overflow(*self, *v); + if y { None } else { Some(x) } + } + } +} + +impl CheckedMul for i64 { + #[inline] + fn checked_mul(&self, v: &i64) -> Option<i64> { + unsafe { + let (x, y) = intrinsics::i64_mul_with_overflow(*self, *v); + if y { None } else { Some(x) } + } + } +} diff --git a/src/libcore/num/i8.rs b/src/libcore/num/i8.rs new file mode 100644 index 00000000000..0d8b9541f7b --- /dev/null +++ b/src/libcore/num/i8.rs @@ -0,0 +1,68 @@ +// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! Operations and constants for signed 8-bits integers (`i8` type) + +use cmp::{Eq, Ord, TotalEq, TotalOrd, Less, Greater, Equal, Ordering}; +use default::Default; +use intrinsics; +use num::{Bitwise, Bounded, Zero, One, Signed, Num, Primitive, Int}; +use num::{CheckedDiv, CheckedAdd, CheckedSub, CheckedMul}; +use ops::{Add, Sub, Mul, Div, Rem, Neg, BitOr, BitAnd, BitXor}; +use ops::{Shl, Shr, Not}; +use option::{Option, Some, None}; + +int_module!(i8, 8) + +impl Bitwise for i8 { + /// Returns the number of ones in the binary representation of the number. + #[inline] + fn count_ones(&self) -> i8 { unsafe { intrinsics::ctpop8(*self as u8) as i8 } } + + /// Returns the number of leading zeros in the in the binary representation + /// of the number. + #[inline] + fn leading_zeros(&self) -> i8 { unsafe { intrinsics::ctlz8(*self as u8) as i8 } } + + /// Returns the number of trailing zeros in the in the binary representation + /// of the number. + #[inline] + fn trailing_zeros(&self) -> i8 { unsafe { intrinsics::cttz8(*self as u8) as i8 } } +} + +impl CheckedAdd for i8 { + #[inline] + fn checked_add(&self, v: &i8) -> Option<i8> { + unsafe { + let (x, y) = intrinsics::i8_add_with_overflow(*self, *v); + if y { None } else { Some(x) } + } + } +} + +impl CheckedSub for i8 { + #[inline] + fn checked_sub(&self, v: &i8) -> Option<i8> { + unsafe { + let (x, y) = intrinsics::i8_sub_with_overflow(*self, *v); + if y { None } else { Some(x) } + } + } +} + +impl CheckedMul for i8 { + #[inline] + fn checked_mul(&self, v: &i8) -> Option<i8> { + unsafe { + let (x, y) = intrinsics::i8_mul_with_overflow(*self, *v); + if y { None } else { Some(x) } + } + } +} diff --git a/src/libcore/num/int.rs b/src/libcore/num/int.rs new file mode 100644 index 00000000000..dacfe987d90 --- /dev/null +++ b/src/libcore/num/int.rs @@ -0,0 +1,123 @@ +// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! Operations and constants for architecture-sized signed integers (`int` type) + +use cmp::{Eq, Ord, TotalEq, TotalOrd, Less, Greater, Equal, Ordering}; +use default::Default; +use intrinsics; +use num::{Bitwise, Bounded, Zero, One, Signed, Num, Primitive, Int}; +use num::{CheckedDiv, CheckedAdd, CheckedSub, CheckedMul}; +use ops::{Add, Sub, Mul, Div, Rem, Neg, BitOr, BitAnd, BitXor}; +use ops::{Shl, Shr, Not}; +use option::{Option, Some, None}; + +#[cfg(target_word_size = "32")] int_module!(int, 32) +#[cfg(target_word_size = "64")] int_module!(int, 64) + +#[cfg(target_word_size = "32")] +impl Bitwise for int { + /// Returns the number of ones in the binary representation of the number. + #[inline] + fn count_ones(&self) -> int { (*self as i32).count_ones() as int } + + /// Returns the number of leading zeros in the in the binary representation + /// of the number. + #[inline] + fn leading_zeros(&self) -> int { (*self as i32).leading_zeros() as int } + + /// Returns the number of trailing zeros in the in the binary representation + /// of the number. + #[inline] + fn trailing_zeros(&self) -> int { (*self as i32).trailing_zeros() as int } +} + +#[cfg(target_word_size = "64")] +impl Bitwise for int { + /// Returns the number of ones in the binary representation of the number. + #[inline] + fn count_ones(&self) -> int { (*self as i64).count_ones() as int } + + /// Returns the number of leading zeros in the in the binary representation + /// of the number. + #[inline] + fn leading_zeros(&self) -> int { (*self as i64).leading_zeros() as int } + + /// Returns the number of trailing zeros in the in the binary representation + /// of the number. + #[inline] + fn trailing_zeros(&self) -> int { (*self as i64).trailing_zeros() as int } +} + +#[cfg(target_word_size = "32")] +impl CheckedAdd for int { + #[inline] + fn checked_add(&self, v: &int) -> Option<int> { + unsafe { + let (x, y) = intrinsics::i32_add_with_overflow(*self as i32, *v as i32); + if y { None } else { Some(x as int) } + } + } +} + +#[cfg(target_word_size = "64")] +impl CheckedAdd for int { + #[inline] + fn checked_add(&self, v: &int) -> Option<int> { + unsafe { + let (x, y) = intrinsics::i64_add_with_overflow(*self as i64, *v as i64); + if y { None } else { Some(x as int) } + } + } +} + +#[cfg(target_word_size = "32")] +impl CheckedSub for int { + #[inline] + fn checked_sub(&self, v: &int) -> Option<int> { + unsafe { + let (x, y) = intrinsics::i32_sub_with_overflow(*self as i32, *v as i32); + if y { None } else { Some(x as int) } + } + } +} + +#[cfg(target_word_size = "64")] +impl CheckedSub for int { + #[inline] + fn checked_sub(&self, v: &int) -> Option<int> { + unsafe { + let (x, y) = intrinsics::i64_sub_with_overflow(*self as i64, *v as i64); + if y { None } else { Some(x as int) } + } + } +} + +#[cfg(target_word_size = "32")] +impl CheckedMul for int { + #[inline] + fn checked_mul(&self, v: &int) -> Option<int> { + unsafe { + let (x, y) = intrinsics::i32_mul_with_overflow(*self as i32, *v as i32); + if y { None } else { Some(x as int) } + } + } +} + +#[cfg(target_word_size = "64")] +impl CheckedMul for int { + #[inline] + fn checked_mul(&self, v: &int) -> Option<int> { + unsafe { + let (x, y) = intrinsics::i64_mul_with_overflow(*self as i64, *v as i64); + if y { None } else { Some(x as int) } + } + } +} diff --git a/src/libcore/num/int_macros.rs b/src/libcore/num/int_macros.rs new file mode 100644 index 00000000000..fc134df9b94 --- /dev/null +++ b/src/libcore/num/int_macros.rs @@ -0,0 +1,337 @@ +// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![macro_escape] +#![doc(hidden)] + +macro_rules! int_module (($T:ty, $bits:expr) => ( + +// FIXME(#11621): Should be deprecated once CTFE is implemented in favour of +// calling the `mem::size_of` function. +pub static BITS : uint = $bits; +// FIXME(#11621): Should be deprecated once CTFE is implemented in favour of +// calling the `mem::size_of` function. +pub static BYTES : uint = ($bits / 8); + +// FIXME(#11621): Should be deprecated once CTFE is implemented in favour of +// calling the `Bounded::min_value` function. +pub static MIN: $T = (-1 as $T) << (BITS - 1); +// FIXME(#9837): Compute MIN like this so the high bits that shouldn't exist are 0. +// FIXME(#11621): Should be deprecated once CTFE is implemented in favour of +// calling the `Bounded::max_value` function. +pub static MAX: $T = !MIN; + +impl Ord for $T { + #[inline] + fn lt(&self, other: &$T) -> bool { *self < *other } +} +impl TotalEq for $T {} +impl Eq for $T { + #[inline] + fn eq(&self, other: &$T) -> bool { *self == *other } +} +impl TotalOrd for $T { + #[inline] + fn cmp(&self, other: &$T) -> Ordering { + if *self < *other { Less } + else if *self > *other { Greater } + else { Equal } + } +} + +impl Num for $T {} + +impl Zero for $T { + #[inline] + fn zero() -> $T { 0 } + + #[inline] + fn is_zero(&self) -> bool { *self == 0 } +} + +impl One for $T { + #[inline] + fn one() -> $T { 1 } +} + +#[cfg(not(test))] +impl Add<$T,$T> for $T { + #[inline] + fn add(&self, other: &$T) -> $T { *self + *other } +} + +#[cfg(not(test))] +impl Sub<$T,$T> for $T { + #[inline] + fn sub(&self, other: &$T) -> $T { *self - *other } +} + +#[cfg(not(test))] +impl Mul<$T,$T> for $T { + #[inline] + fn mul(&self, other: &$T) -> $T { *self * *other } +} + +#[cfg(not(test))] +impl Div<$T,$T> for $T { + /// Integer division, truncated towards 0. + /// + /// # Examples + /// + /// ~~~ + /// assert!( 8 / 3 == 2); + /// assert!( 8 / -3 == -2); + /// assert!(-8 / 3 == -2); + /// assert!(-8 / -3 == 2); + /// + /// assert!( 1 / 2 == 0); + /// assert!( 1 / -2 == 0); + /// assert!(-1 / 2 == 0); + /// assert!(-1 / -2 == 0); + /// ~~~ + #[inline] + fn div(&self, other: &$T) -> $T { *self / *other } +} + +#[cfg(not(test))] +impl Rem<$T,$T> for $T { + /// Returns the integer remainder after division, satisfying: + /// + /// ~~~ + /// # let n = 1; + /// # let d = 2; + /// assert!((n / d) * d + (n % d) == n) + /// ~~~ + /// + /// # Examples + /// + /// ~~~ + /// assert!( 8 % 3 == 2); + /// assert!( 8 % -3 == 2); + /// assert!(-8 % 3 == -2); + /// assert!(-8 % -3 == -2); + /// + /// assert!( 1 % 2 == 1); + /// assert!( 1 % -2 == 1); + /// assert!(-1 % 2 == -1); + /// assert!(-1 % -2 == -1); + /// ~~~ + #[inline] + fn rem(&self, other: &$T) -> $T { *self % *other } +} + +#[cfg(not(test))] +impl Neg<$T> for $T { + #[inline] + fn neg(&self) -> $T { -*self } +} + +impl Signed for $T { + /// Computes the absolute value + #[inline] + fn abs(&self) -> $T { + if self.is_negative() { -*self } else { *self } + } + + /// + /// The positive difference of two numbers. Returns `0` if the number is less than or + /// equal to `other`, otherwise the difference between`self` and `other` is returned. + /// + #[inline] + fn abs_sub(&self, other: &$T) -> $T { + if *self <= *other { 0 } else { *self - *other } + } + + /// + /// # Returns + /// + /// - `0` if the number is zero + /// - `1` if the number is positive + /// - `-1` if the number is negative + /// + #[inline] + fn signum(&self) -> $T { + match *self { + n if n > 0 => 1, + 0 => 0, + _ => -1, + } + } + + /// Returns true if the number is positive + #[inline] + fn is_positive(&self) -> bool { *self > 0 } + + /// Returns true if the number is negative + #[inline] + fn is_negative(&self) -> bool { *self < 0 } +} + +#[cfg(not(test))] +impl BitOr<$T,$T> for $T { + #[inline] + fn bitor(&self, other: &$T) -> $T { *self | *other } +} + +#[cfg(not(test))] +impl BitAnd<$T,$T> for $T { + #[inline] + fn bitand(&self, other: &$T) -> $T { *self & *other } +} + +#[cfg(not(test))] +impl BitXor<$T,$T> for $T { + #[inline] + fn bitxor(&self, other: &$T) -> $T { *self ^ *other } +} + +#[cfg(not(test))] +impl Shl<$T,$T> for $T { + #[inline] + fn shl(&self, other: &$T) -> $T { *self << *other } +} + +#[cfg(not(test))] +impl Shr<$T,$T> for $T { + #[inline] + fn shr(&self, other: &$T) -> $T { *self >> *other } +} + +#[cfg(not(test))] +impl Not<$T> for $T { + #[inline] + fn not(&self) -> $T { !*self } +} + +impl Bounded for $T { + #[inline] + fn min_value() -> $T { MIN } + + #[inline] + fn max_value() -> $T { MAX } +} + +impl CheckedDiv for $T { + #[inline] + fn checked_div(&self, v: &$T) -> Option<$T> { + if *v == 0 { + None + } else { + Some(self / *v) + } + } +} + +impl Default for $T { + #[inline] + fn default() -> $T { 0 } +} + +impl Int for $T {} + +impl Primitive for $T {} + +#[cfg(test)] +mod tests { + use prelude::*; + use super::*; + + use int; + use i32; + use num; + use num::Bitwise; + use num::CheckedDiv; + use num::ToStrRadix; + use str::StrSlice; + + #[test] + fn test_overflows() { + assert!(MAX > 0); + assert!(MIN <= 0); + assert_eq!(MIN + MAX + 1, 0); + } + + #[test] + fn test_num() { + num::test_num(10 as $T, 2 as $T); + } + + #[test] + pub fn test_abs() { + assert_eq!((1 as $T).abs(), 1 as $T); + assert_eq!((0 as $T).abs(), 0 as $T); + assert_eq!((-1 as $T).abs(), 1 as $T); + } + + #[test] + fn test_abs_sub() { + assert_eq!((-1 as $T).abs_sub(&(1 as $T)), 0 as $T); + assert_eq!((1 as $T).abs_sub(&(1 as $T)), 0 as $T); + assert_eq!((1 as $T).abs_sub(&(0 as $T)), 1 as $T); + assert_eq!((1 as $T).abs_sub(&(-1 as $T)), 2 as $T); + } + + #[test] + fn test_signum() { + assert_eq!((1 as $T).signum(), 1 as $T); + assert_eq!((0 as $T).signum(), 0 as $T); + assert_eq!((-0 as $T).signum(), 0 as $T); + assert_eq!((-1 as $T).signum(), -1 as $T); + } + + #[test] + fn test_is_positive() { + assert!((1 as $T).is_positive()); + assert!(!(0 as $T).is_positive()); + assert!(!(-0 as $T).is_positive()); + assert!(!(-1 as $T).is_positive()); + } + + #[test] + fn test_is_negative() { + assert!(!(1 as $T).is_negative()); + assert!(!(0 as $T).is_negative()); + assert!(!(-0 as $T).is_negative()); + assert!((-1 as $T).is_negative()); + } + + #[test] + fn test_bitwise() { + assert_eq!(0b1110 as $T, (0b1100 as $T).bitor(&(0b1010 as $T))); + assert_eq!(0b1000 as $T, (0b1100 as $T).bitand(&(0b1010 as $T))); + assert_eq!(0b0110 as $T, (0b1100 as $T).bitxor(&(0b1010 as $T))); + assert_eq!(0b1110 as $T, (0b0111 as $T).shl(&(1 as $T))); + assert_eq!(0b0111 as $T, (0b1110 as $T).shr(&(1 as $T))); + assert_eq!(-(0b11 as $T) - (1 as $T), (0b11 as $T).not()); + } + + #[test] + fn test_count_ones() { + assert_eq!((0b0101100 as $T).count_ones(), 3); + assert_eq!((0b0100001 as $T).count_ones(), 2); + assert_eq!((0b1111001 as $T).count_ones(), 5); + } + + #[test] + fn test_count_zeros() { + assert_eq!((0b0101100 as $T).count_zeros(), BITS as $T - 3); + assert_eq!((0b0100001 as $T).count_zeros(), BITS as $T - 2); + assert_eq!((0b1111001 as $T).count_zeros(), BITS as $T - 5); + } + + #[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.checked_div(&-1), None); + } +} + +)) diff --git a/src/libcore/num/u16.rs b/src/libcore/num/u16.rs new file mode 100644 index 00000000000..92afe4955a8 --- /dev/null +++ b/src/libcore/num/u16.rs @@ -0,0 +1,52 @@ +// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! Operations and constants for unsigned 16-bits integers (`u16` type) + +use cmp::{Eq, Ord, TotalEq, TotalOrd, Less, Greater, Equal, Ordering}; +use default::Default; +use intrinsics; +use num::{Bitwise, Bounded, Zero, One, Unsigned, Num, Int, Primitive}; +use num::{CheckedAdd, CheckedSub, CheckedMul, CheckedDiv}; +use ops::{Add, Sub, Mul, Div, Rem, Neg, BitAnd, BitOr, BitXor}; +use ops::{Shl, Shr, Not}; +use option::{Some, None, Option}; + +uint_module!(u16, i16, 16) + +impl CheckedAdd for u16 { + #[inline] + fn checked_add(&self, v: &u16) -> Option<u16> { + unsafe { + let (x, y) = intrinsics::u16_add_with_overflow(*self, *v); + if y { None } else { Some(x) } + } + } +} + +impl CheckedSub for u16 { + #[inline] + fn checked_sub(&self, v: &u16) -> Option<u16> { + unsafe { + let (x, y) = intrinsics::u16_sub_with_overflow(*self, *v); + if y { None } else { Some(x) } + } + } +} + +impl CheckedMul for u16 { + #[inline] + fn checked_mul(&self, v: &u16) -> Option<u16> { + unsafe { + let (x, y) = intrinsics::u16_mul_with_overflow(*self, *v); + if y { None } else { Some(x) } + } + } +} diff --git a/src/libcore/num/u32.rs b/src/libcore/num/u32.rs new file mode 100644 index 00000000000..2cac95e5c3b --- /dev/null +++ b/src/libcore/num/u32.rs @@ -0,0 +1,52 @@ +// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! Operations and constants for unsigned 32-bits integers (`u32` type) + +use cmp::{Eq, Ord, TotalEq, TotalOrd, Less, Greater, Equal, Ordering}; +use default::Default; +use intrinsics; +use num::{Bitwise, Bounded, Zero, One, Unsigned, Num, Int, Primitive}; +use num::{CheckedAdd, CheckedSub, CheckedMul, CheckedDiv}; +use ops::{Add, Sub, Mul, Div, Rem, Neg, BitAnd, BitOr, BitXor}; +use ops::{Shl, Shr, Not}; +use option::{Some, None, Option}; + +uint_module!(u32, i32, 32) + +impl CheckedAdd for u32 { + #[inline] + fn checked_add(&self, v: &u32) -> Option<u32> { + unsafe { + let (x, y) = intrinsics::u32_add_with_overflow(*self, *v); + if y { None } else { Some(x) } + } + } +} + +impl CheckedSub for u32 { + #[inline] + fn checked_sub(&self, v: &u32) -> Option<u32> { + unsafe { + let (x, y) = intrinsics::u32_sub_with_overflow(*self, *v); + if y { None } else { Some(x) } + } + } +} + +impl CheckedMul for u32 { + #[inline] + fn checked_mul(&self, v: &u32) -> Option<u32> { + unsafe { + let (x, y) = intrinsics::u32_mul_with_overflow(*self, *v); + if y { None } else { Some(x) } + } + } +} diff --git a/src/libcore/num/u64.rs b/src/libcore/num/u64.rs new file mode 100644 index 00000000000..7b6498b5a69 --- /dev/null +++ b/src/libcore/num/u64.rs @@ -0,0 +1,52 @@ +// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! Operations and constants for unsigned 64-bits integer (`u64` type) + +use cmp::{Eq, Ord, TotalEq, TotalOrd, Less, Greater, Equal, Ordering}; +use default::Default; +use intrinsics; +use num::{Bitwise, Bounded, Zero, One, Unsigned, Num, Int, Primitive}; +use num::{CheckedAdd, CheckedSub, CheckedMul, CheckedDiv}; +use ops::{Add, Sub, Mul, Div, Rem, Neg, BitAnd, BitOr, BitXor}; +use ops::{Shl, Shr, Not}; +use option::{Some, None, Option}; + +uint_module!(u64, i64, 64) + +impl CheckedAdd for u64 { + #[inline] + fn checked_add(&self, v: &u64) -> Option<u64> { + unsafe { + let (x, y) = intrinsics::u64_add_with_overflow(*self, *v); + if y { None } else { Some(x) } + } + } +} + +impl CheckedSub for u64 { + #[inline] + fn checked_sub(&self, v: &u64) -> Option<u64> { + unsafe { + let (x, y) = intrinsics::u64_sub_with_overflow(*self, *v); + if y { None } else { Some(x) } + } + } +} + +impl CheckedMul for u64 { + #[inline] + fn checked_mul(&self, v: &u64) -> Option<u64> { + unsafe { + let (x, y) = intrinsics::u64_mul_with_overflow(*self, *v); + if y { None } else { Some(x) } + } + } +} diff --git a/src/libcore/num/u8.rs b/src/libcore/num/u8.rs new file mode 100644 index 00000000000..6916c0c9f32 --- /dev/null +++ b/src/libcore/num/u8.rs @@ -0,0 +1,52 @@ +// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! Operations and constants for unsigned 8-bits integers (`u8` type) + +use cmp::{Eq, Ord, TotalEq, TotalOrd, Less, Greater, Equal, Ordering}; +use default::Default; +use intrinsics; +use num::{Bitwise, Bounded, Zero, One, Unsigned, Num, Int, Primitive}; +use num::{CheckedAdd, CheckedSub, CheckedMul, CheckedDiv}; +use ops::{Add, Sub, Mul, Div, Rem, Neg, BitAnd, BitOr, BitXor}; +use ops::{Shl, Shr, Not}; +use option::{Some, None, Option}; + +uint_module!(u8, i8, 8) + +impl CheckedAdd for u8 { + #[inline] + fn checked_add(&self, v: &u8) -> Option<u8> { + unsafe { + let (x, y) = intrinsics::u8_add_with_overflow(*self, *v); + if y { None } else { Some(x) } + } + } +} + +impl CheckedSub for u8 { + #[inline] + fn checked_sub(&self, v: &u8) -> Option<u8> { + unsafe { + let (x, y) = intrinsics::u8_sub_with_overflow(*self, *v); + if y { None } else { Some(x) } + } + } +} + +impl CheckedMul for u8 { + #[inline] + fn checked_mul(&self, v: &u8) -> Option<u8> { + unsafe { + let (x, y) = intrinsics::u8_mul_with_overflow(*self, *v); + if y { None } else { Some(x) } + } + } +} diff --git a/src/libcore/num/uint.rs b/src/libcore/num/uint.rs new file mode 100644 index 00000000000..40e4b8327dd --- /dev/null +++ b/src/libcore/num/uint.rs @@ -0,0 +1,88 @@ +// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! Operations and constants for architecture-sized unsigned integers (`uint` type) + +use cmp::{Eq, Ord, TotalEq, TotalOrd, Less, Greater, Equal, Ordering}; +use default::Default; +use intrinsics; +use num::{Bitwise, Bounded, Zero, One, Unsigned, Num, Int, Primitive}; +use num::{CheckedAdd, CheckedSub, CheckedMul, CheckedDiv}; +use ops::{Add, Sub, Mul, Div, Rem, Neg, BitAnd, BitOr, BitXor}; +use ops::{Shl, Shr, Not}; +use option::{Some, None, Option}; + +uint_module!(uint, int, ::int::BITS) + +#[cfg(target_word_size = "32")] +impl CheckedAdd for uint { + #[inline] + fn checked_add(&self, v: &uint) -> Option<uint> { + unsafe { + let (x, y) = intrinsics::u32_add_with_overflow(*self as u32, *v as u32); + if y { None } else { Some(x as uint) } + } + } +} + +#[cfg(target_word_size = "64")] +impl CheckedAdd for uint { + #[inline] + fn checked_add(&self, v: &uint) -> Option<uint> { + unsafe { + let (x, y) = intrinsics::u64_add_with_overflow(*self as u64, *v as u64); + if y { None } else { Some(x as uint) } + } + } +} + +#[cfg(target_word_size = "32")] +impl CheckedSub for uint { + #[inline] + fn checked_sub(&self, v: &uint) -> Option<uint> { + unsafe { + let (x, y) = intrinsics::u32_sub_with_overflow(*self as u32, *v as u32); + if y { None } else { Some(x as uint) } + } + } +} + +#[cfg(target_word_size = "64")] +impl CheckedSub for uint { + #[inline] + fn checked_sub(&self, v: &uint) -> Option<uint> { + unsafe { + let (x, y) = intrinsics::u64_sub_with_overflow(*self as u64, *v as u64); + if y { None } else { Some(x as uint) } + } + } +} + +#[cfg(target_word_size = "32")] +impl CheckedMul for uint { + #[inline] + fn checked_mul(&self, v: &uint) -> Option<uint> { + unsafe { + let (x, y) = intrinsics::u32_mul_with_overflow(*self as u32, *v as u32); + if y { None } else { Some(x as uint) } + } + } +} + +#[cfg(target_word_size = "64")] +impl CheckedMul for uint { + #[inline] + fn checked_mul(&self, v: &uint) -> Option<uint> { + unsafe { + let (x, y) = intrinsics::u64_mul_with_overflow(*self as u64, *v as u64); + if y { None } else { Some(x as uint) } + } + } +} diff --git a/src/libcore/num/uint_macros.rs b/src/libcore/num/uint_macros.rs new file mode 100644 index 00000000000..3ef785a0462 --- /dev/null +++ b/src/libcore/num/uint_macros.rs @@ -0,0 +1,234 @@ +// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![macro_escape] +#![doc(hidden)] + +macro_rules! uint_module (($T:ty, $T_SIGNED:ty, $bits:expr) => ( + +pub static BITS : uint = $bits; +pub static BYTES : uint = ($bits / 8); + +pub static MIN: $T = 0 as $T; +pub static MAX: $T = 0 as $T - 1 as $T; + +impl Ord for $T { + #[inline] + fn lt(&self, other: &$T) -> bool { *self < *other } +} +impl TotalEq for $T {} +impl Eq for $T { + #[inline] + fn eq(&self, other: &$T) -> bool { *self == *other } +} +impl TotalOrd for $T { + #[inline] + fn cmp(&self, other: &$T) -> Ordering { + if *self < *other { Less } + else if *self > *other { Greater } + else { Equal } + } +} + +impl Num for $T {} + +impl Zero for $T { + #[inline] + fn zero() -> $T { 0 } + + #[inline] + fn is_zero(&self) -> bool { *self == 0 } +} + +impl One for $T { + #[inline] + fn one() -> $T { 1 } +} + +#[cfg(not(test))] +impl Add<$T,$T> for $T { + #[inline] + fn add(&self, other: &$T) -> $T { *self + *other } +} + +#[cfg(not(test))] +impl Sub<$T,$T> for $T { + #[inline] + fn sub(&self, other: &$T) -> $T { *self - *other } +} + +#[cfg(not(test))] +impl Mul<$T,$T> for $T { + #[inline] + fn mul(&self, other: &$T) -> $T { *self * *other } +} + +#[cfg(not(test))] +impl Div<$T,$T> for $T { + #[inline] + fn div(&self, other: &$T) -> $T { *self / *other } +} + +#[cfg(not(test))] +impl Rem<$T,$T> for $T { + #[inline] + fn rem(&self, other: &$T) -> $T { *self % *other } +} + +#[cfg(not(test))] +impl Neg<$T> for $T { + #[inline] + fn neg(&self) -> $T { -*self } +} + +impl Unsigned for $T {} + +#[cfg(not(test))] +impl BitOr<$T,$T> for $T { + #[inline] + fn bitor(&self, other: &$T) -> $T { *self | *other } +} + +#[cfg(not(test))] +impl BitAnd<$T,$T> for $T { + #[inline] + fn bitand(&self, other: &$T) -> $T { *self & *other } +} + +#[cfg(not(test))] +impl BitXor<$T,$T> for $T { + #[inline] + fn bitxor(&self, other: &$T) -> $T { *self ^ *other } +} + +#[cfg(not(test))] +impl Shl<$T,$T> for $T { + #[inline] + fn shl(&self, other: &$T) -> $T { *self << *other } +} + +#[cfg(not(test))] +impl Shr<$T,$T> for $T { + #[inline] + fn shr(&self, other: &$T) -> $T { *self >> *other } +} + +#[cfg(not(test))] +impl Not<$T> for $T { + #[inline] + fn not(&self) -> $T { !*self } +} + +impl Bounded for $T { + #[inline] + fn min_value() -> $T { MIN } + + #[inline] + fn max_value() -> $T { MAX } +} + +impl Bitwise for $T { + /// Returns the number of ones in the binary representation of the number. + #[inline] + fn count_ones(&self) -> $T { + (*self as $T_SIGNED).count_ones() as $T + } + + /// Returns the number of leading zeros in the in the binary representation + /// of the number. + #[inline] + fn leading_zeros(&self) -> $T { + (*self as $T_SIGNED).leading_zeros() as $T + } + + /// Returns the number of trailing zeros in the in the binary representation + /// of the number. + #[inline] + fn trailing_zeros(&self) -> $T { + (*self as $T_SIGNED).trailing_zeros() as $T + } +} + +impl CheckedDiv for $T { + #[inline] + fn checked_div(&self, v: &$T) -> Option<$T> { + if *v == 0 { + None + } else { + Some(self / *v) + } + } +} + +impl Int for $T {} + +impl Primitive for $T {} + +impl Default for $T { + #[inline] + fn default() -> $T { 0 } +} + +#[cfg(test)] +mod tests { + use prelude::*; + use super::*; + + use num; + use num::CheckedDiv; + use num::Bitwise; + use num::ToStrRadix; + use str::StrSlice; + use u16; + + #[test] + fn test_overflows() { + assert!(MAX > 0); + assert!(MIN <= 0); + assert_eq!(MIN + MAX + 1, 0); + } + + #[test] + fn test_num() { + num::test_num(10 as $T, 2 as $T); + } + + #[test] + fn test_bitwise() { + assert_eq!(0b1110 as $T, (0b1100 as $T).bitor(&(0b1010 as $T))); + assert_eq!(0b1000 as $T, (0b1100 as $T).bitand(&(0b1010 as $T))); + assert_eq!(0b0110 as $T, (0b1100 as $T).bitxor(&(0b1010 as $T))); + assert_eq!(0b1110 as $T, (0b0111 as $T).shl(&(1 as $T))); + assert_eq!(0b0111 as $T, (0b1110 as $T).shr(&(1 as $T))); + assert_eq!(MAX - (0b1011 as $T), (0b1011 as $T).not()); + } + + #[test] + fn test_count_ones() { + assert_eq!((0b0101100 as $T).count_ones(), 3); + assert_eq!((0b0100001 as $T).count_ones(), 2); + assert_eq!((0b1111001 as $T).count_ones(), 5); + } + + #[test] + fn test_count_zeros() { + assert_eq!((0b0101100 as $T).count_zeros(), BITS as $T - 3); + assert_eq!((0b0100001 as $T).count_zeros(), BITS as $T - 2); + assert_eq!((0b1111001 as $T).count_zeros(), BITS as $T - 5); + } + + #[test] + fn test_unsigned_checked_div() { + assert_eq!(10u.checked_div(&2), Some(5)); + assert_eq!(5u.checked_div(&0), None); + } +} + +)) diff --git a/src/libstd/num/f32.rs b/src/libstd/num/f32.rs index 672de0bf9e5..ea248b6d40d 100644 --- a/src/libstd/num/f32.rs +++ b/src/libstd/num/f32.rs @@ -16,14 +16,18 @@ use prelude::*; use cast; -use default::Default; use from_str::FromStr; -use libc::{c_int}; +use libc::c_int; use num::{FPCategory, FPNaN, FPInfinite , FPZero, FPSubnormal, FPNormal}; -use num::{Zero, One, Bounded, strconv}; +use num::strconv; use num; use intrinsics; +pub use core::f32::{RADIX, MANTISSA_DIGITS, DIGITS, EPSILON, MIN_VALUE}; +pub use core::f32::{MIN_POS_VALUE, MAX_VALUE, MIN_EXP, MAX_EXP, MIN_10_EXP}; +pub use core::f32::{MAX_10_EXP, NAN, INFINITY, NEG_INFINITY}; +pub use core::f32::consts; + #[allow(dead_code)] mod cmath { use libc::{c_float, c_int}; @@ -65,214 +69,6 @@ mod cmath { } } -pub static RADIX: uint = 2u; - -pub static MANTISSA_DIGITS: uint = 24u; -pub static DIGITS: uint = 6u; - -pub static EPSILON: f32 = 1.19209290e-07_f32; - -/// Smallest finite f32 value -pub static MIN_VALUE: f32 = -3.40282347e+38_f32; -/// Smallest positive, normalized f32 value -pub static MIN_POS_VALUE: f32 = 1.17549435e-38_f32; -/// Largest finite f32 value -pub static MAX_VALUE: f32 = 3.40282347e+38_f32; - -pub static MIN_EXP: int = -125; -pub static MAX_EXP: int = 128; - -pub static MIN_10_EXP: int = -37; -pub static MAX_10_EXP: int = 38; - -pub static NAN: f32 = 0.0_f32/0.0_f32; -pub static INFINITY: f32 = 1.0_f32/0.0_f32; -pub static NEG_INFINITY: f32 = -1.0_f32/0.0_f32; - -/// Various useful constants. -pub mod consts { - // FIXME: replace with mathematical constants from cmath. - - // FIXME(#5527): These constants should be deprecated once associated - // constants are implemented in favour of referencing the respective members - // of `Float`. - - /// Archimedes' constant - pub static PI: f32 = 3.14159265358979323846264338327950288_f32; - - /// pi * 2.0 - pub static PI_2: f32 = 6.28318530717958647692528676655900576_f32; - - /// pi/2.0 - pub static FRAC_PI_2: f32 = 1.57079632679489661923132169163975144_f32; - - /// pi/3.0 - pub static FRAC_PI_3: f32 = 1.04719755119659774615421446109316763_f32; - - /// pi/4.0 - pub static FRAC_PI_4: f32 = 0.785398163397448309615660845819875721_f32; - - /// pi/6.0 - pub static FRAC_PI_6: f32 = 0.52359877559829887307710723054658381_f32; - - /// pi/8.0 - pub static FRAC_PI_8: f32 = 0.39269908169872415480783042290993786_f32; - - /// 1.0/pi - pub static FRAC_1_PI: f32 = 0.318309886183790671537767526745028724_f32; - - /// 2.0/pi - pub static FRAC_2_PI: f32 = 0.636619772367581343075535053490057448_f32; - - /// 2.0/sqrt(pi) - pub static FRAC_2_SQRTPI: f32 = 1.12837916709551257389615890312154517_f32; - - /// sqrt(2.0) - pub static SQRT2: f32 = 1.41421356237309504880168872420969808_f32; - - /// 1.0/sqrt(2.0) - pub static FRAC_1_SQRT2: f32 = 0.707106781186547524400844362104849039_f32; - - /// Euler's number - pub static E: f32 = 2.71828182845904523536028747135266250_f32; - - /// log2(e) - pub static LOG2_E: f32 = 1.44269504088896340735992468100189214_f32; - - /// log10(e) - pub static LOG10_E: f32 = 0.434294481903251827651128918916605082_f32; - - /// ln(2.0) - pub static LN_2: f32 = 0.693147180559945309417232121458176568_f32; - - /// ln(10.0) - pub static LN_10: f32 = 2.30258509299404568401799145468436421_f32; -} - -impl Num for f32 {} - -#[cfg(not(test))] -impl Eq for f32 { - #[inline] - fn eq(&self, other: &f32) -> bool { (*self) == (*other) } -} - -#[cfg(not(test))] -impl Ord for f32 { - #[inline] - fn lt(&self, other: &f32) -> bool { (*self) < (*other) } - #[inline] - fn le(&self, other: &f32) -> bool { (*self) <= (*other) } - #[inline] - fn ge(&self, other: &f32) -> bool { (*self) >= (*other) } - #[inline] - fn gt(&self, other: &f32) -> bool { (*self) > (*other) } -} - -impl Default for f32 { - #[inline] - fn default() -> f32 { 0.0 } -} - -impl Zero for f32 { - #[inline] - fn zero() -> f32 { 0.0 } - - /// Returns true if the number is equal to either `0.0` or `-0.0` - #[inline] - fn is_zero(&self) -> bool { *self == 0.0 || *self == -0.0 } -} - -impl One for f32 { - #[inline] - fn one() -> f32 { 1.0 } -} - -#[cfg(not(test))] -impl Add<f32,f32> for f32 { - #[inline] - fn add(&self, other: &f32) -> f32 { *self + *other } -} - -#[cfg(not(test))] -impl Sub<f32,f32> for f32 { - #[inline] - fn sub(&self, other: &f32) -> f32 { *self - *other } -} - -#[cfg(not(test))] -impl Mul<f32,f32> for f32 { - #[inline] - fn mul(&self, other: &f32) -> f32 { *self * *other } -} - -#[cfg(not(test))] -impl Div<f32,f32> for f32 { - #[inline] - fn div(&self, other: &f32) -> f32 { *self / *other } -} - -#[cfg(not(test))] -impl Rem<f32,f32> for f32 { - #[inline] - fn rem(&self, other: &f32) -> f32 { - unsafe { cmath::fmodf(*self, *other) } - } -} - -#[cfg(not(test))] -impl Neg<f32> for f32 { - #[inline] - fn neg(&self) -> f32 { -*self } -} - -impl Signed for f32 { - /// Computes the absolute value. Returns `NAN` if the number is `NAN`. - #[inline] - fn abs(&self) -> f32 { - unsafe { intrinsics::fabsf32(*self) } - } - - /// The positive difference of two numbers. Returns `0.0` if the number is - /// less than or equal to `other`, otherwise the difference between`self` - /// and `other` is returned. - #[inline] - fn abs_sub(&self, other: &f32) -> f32 { - unsafe { cmath::fdimf(*self, *other) } - } - - /// # Returns - /// - /// - `1.0` if the number is positive, `+0.0` or `INFINITY` - /// - `-1.0` if the number is negative, `-0.0` or `NEG_INFINITY` - /// - `NAN` if the number is NaN - #[inline] - fn signum(&self) -> f32 { - if self.is_nan() { NAN } else { - unsafe { intrinsics::copysignf32(1.0, *self) } - } - } - - /// Returns `true` if the number is positive, including `+0.0` and `INFINITY` - #[inline] - fn is_positive(&self) -> bool { *self > 0.0 || (1.0 / *self) == INFINITY } - - /// Returns `true` if the number is negative, including `-0.0` and `NEG_INFINITY` - #[inline] - fn is_negative(&self) -> bool { *self < 0.0 || (1.0 / *self) == NEG_INFINITY } -} - -impl Bounded for f32 { - // NOTE: this is the smallest non-infinite f32 value, *not* MIN_VALUE - #[inline] - fn min_value() -> f32 { -MAX_VALUE } - - #[inline] - fn max_value() -> f32 { MAX_VALUE } -} - -impl Primitive for f32 {} - impl Float for f32 { #[inline] fn nan() -> f32 { NAN } diff --git a/src/libstd/num/f64.rs b/src/libstd/num/f64.rs index 6523ac9e8a4..77171a00bef 100644 --- a/src/libstd/num/f64.rs +++ b/src/libstd/num/f64.rs @@ -15,14 +15,18 @@ use prelude::*; use cast; -use default::Default; use from_str::FromStr; use libc::{c_int}; use num::{FPCategory, FPNaN, FPInfinite , FPZero, FPSubnormal, FPNormal}; -use num::{Zero, One, Bounded, strconv}; +use num::{strconv}; use num; use intrinsics; +pub use core::f64::{RADIX, MANTISSA_DIGITS, DIGITS, EPSILON, MIN_VALUE}; +pub use core::f64::{MIN_POS_VALUE, MAX_VALUE, MIN_EXP, MAX_EXP, MIN_10_EXP}; +pub use core::f64::{MAX_10_EXP, NAN, INFINITY, NEG_INFINITY}; +pub use core::f64::consts; + #[allow(dead_code)] mod cmath { use libc::{c_double, c_int}; @@ -73,214 +77,6 @@ mod cmath { } } -// FIXME(#5527): These constants should be deprecated once associated -// constants are implemented in favour of referencing the respective -// members of `Bounded` and `Float`. - -pub static RADIX: uint = 2u; - -pub static MANTISSA_DIGITS: uint = 53u; -pub static DIGITS: uint = 15u; - -pub static EPSILON: f64 = 2.2204460492503131e-16_f64; - -/// Smallest finite f64 value -pub static MIN_VALUE: f64 = -1.7976931348623157e+308_f64; -/// Smallest positive, normalized f64 value -pub static MIN_POS_VALUE: f64 = 2.2250738585072014e-308_f64; -/// Largest finite f64 value -pub static MAX_VALUE: f64 = 1.7976931348623157e+308_f64; - -pub static MIN_EXP: int = -1021; -pub static MAX_EXP: int = 1024; - -pub static MIN_10_EXP: int = -307; -pub static MAX_10_EXP: int = 308; - -pub static NAN: f64 = 0.0_f64/0.0_f64; - -pub static INFINITY: f64 = 1.0_f64/0.0_f64; - -pub static NEG_INFINITY: f64 = -1.0_f64/0.0_f64; - -/// Various useful constants. -pub mod consts { - // FIXME: replace with mathematical constants from cmath. - - // FIXME(#5527): These constants should be deprecated once associated - // constants are implemented in favour of referencing the respective members - // of `Float`. - - /// Archimedes' constant - pub static PI: f64 = 3.14159265358979323846264338327950288_f64; - - /// pi * 2.0 - pub static PI_2: f64 = 6.28318530717958647692528676655900576_f64; - - /// pi/2.0 - pub static FRAC_PI_2: f64 = 1.57079632679489661923132169163975144_f64; - - /// pi/3.0 - pub static FRAC_PI_3: f64 = 1.04719755119659774615421446109316763_f64; - - /// pi/4.0 - pub static FRAC_PI_4: f64 = 0.785398163397448309615660845819875721_f64; - - /// pi/6.0 - pub static FRAC_PI_6: f64 = 0.52359877559829887307710723054658381_f64; - - /// pi/8.0 - pub static FRAC_PI_8: f64 = 0.39269908169872415480783042290993786_f64; - - /// 1.0/pi - pub static FRAC_1_PI: f64 = 0.318309886183790671537767526745028724_f64; - - /// 2.0/pi - pub static FRAC_2_PI: f64 = 0.636619772367581343075535053490057448_f64; - - /// 2.0/sqrt(pi) - pub static FRAC_2_SQRTPI: f64 = 1.12837916709551257389615890312154517_f64; - - /// sqrt(2.0) - pub static SQRT2: f64 = 1.41421356237309504880168872420969808_f64; - - /// 1.0/sqrt(2.0) - pub static FRAC_1_SQRT2: f64 = 0.707106781186547524400844362104849039_f64; - - /// Euler's number - pub static E: f64 = 2.71828182845904523536028747135266250_f64; - - /// log2(e) - pub static LOG2_E: f64 = 1.44269504088896340735992468100189214_f64; - - /// log10(e) - pub static LOG10_E: f64 = 0.434294481903251827651128918916605082_f64; - - /// ln(2.0) - pub static LN_2: f64 = 0.693147180559945309417232121458176568_f64; - - /// ln(10.0) - pub static LN_10: f64 = 2.30258509299404568401799145468436421_f64; -} - -impl Num for f64 {} - -#[cfg(not(test))] -impl Eq for f64 { - #[inline] - fn eq(&self, other: &f64) -> bool { (*self) == (*other) } -} - -#[cfg(not(test))] -impl Ord for f64 { - #[inline] - fn lt(&self, other: &f64) -> bool { (*self) < (*other) } - #[inline] - fn le(&self, other: &f64) -> bool { (*self) <= (*other) } - #[inline] - fn ge(&self, other: &f64) -> bool { (*self) >= (*other) } - #[inline] - fn gt(&self, other: &f64) -> bool { (*self) > (*other) } -} - -impl Default for f64 { - #[inline] - fn default() -> f64 { 0.0 } -} - -impl Zero for f64 { - #[inline] - fn zero() -> f64 { 0.0 } - - /// Returns true if the number is equal to either `0.0` or `-0.0` - #[inline] - fn is_zero(&self) -> bool { *self == 0.0 || *self == -0.0 } -} - -impl One for f64 { - #[inline] - fn one() -> f64 { 1.0 } -} - -#[cfg(not(test))] -impl Add<f64,f64> for f64 { - #[inline] - fn add(&self, other: &f64) -> f64 { *self + *other } -} -#[cfg(not(test))] -impl Sub<f64,f64> for f64 { - #[inline] - fn sub(&self, other: &f64) -> f64 { *self - *other } -} -#[cfg(not(test))] -impl Mul<f64,f64> for f64 { - #[inline] - fn mul(&self, other: &f64) -> f64 { *self * *other } -} -#[cfg(not(test))] -impl Div<f64,f64> for f64 { - #[inline] - fn div(&self, other: &f64) -> f64 { *self / *other } -} -#[cfg(not(test))] -impl Rem<f64,f64> for f64 { - #[inline] - fn rem(&self, other: &f64) -> f64 { - unsafe { cmath::fmod(*self, *other) } - } -} -#[cfg(not(test))] -impl Neg<f64> for f64 { - #[inline] - fn neg(&self) -> f64 { -*self } -} - -impl Signed for f64 { - /// Computes the absolute value. Returns `NAN` if the number is `NAN`. - #[inline] - fn abs(&self) -> f64 { - unsafe { intrinsics::fabsf64(*self) } - } - - /// The positive difference of two numbers. Returns `0.0` if the number is less than or - /// equal to `other`, otherwise the difference between`self` and `other` is returned. - #[inline] - fn abs_sub(&self, other: &f64) -> f64 { - unsafe { cmath::fdim(*self, *other) } - } - - /// # Returns - /// - /// - `1.0` if the number is positive, `+0.0` or `INFINITY` - /// - `-1.0` if the number is negative, `-0.0` or `NEG_INFINITY` - /// - `NAN` if the number is NaN - #[inline] - fn signum(&self) -> f64 { - if self.is_nan() { NAN } else { - unsafe { intrinsics::copysignf64(1.0, *self) } - } - } - - /// Returns `true` if the number is positive, including `+0.0` and `INFINITY` - #[inline] - fn is_positive(&self) -> bool { *self > 0.0 || (1.0 / *self) == INFINITY } - - /// Returns `true` if the number is negative, including `-0.0` and `NEG_INFINITY` - #[inline] - fn is_negative(&self) -> bool { *self < 0.0 || (1.0 / *self) == NEG_INFINITY } -} - -impl Bounded for f64 { - // NOTE: this is the smallest non-infinite f32 value, *not* MIN_VALUE - #[inline] - fn min_value() -> f64 { -MAX_VALUE } - - #[inline] - fn max_value() -> f64 { MAX_VALUE } -} - -impl Primitive for f64 {} - impl Float for f64 { #[inline] fn nan() -> f64 { NAN } diff --git a/src/libstd/num/i16.rs b/src/libstd/num/i16.rs index 79827421f92..4bd2ba07634 100644 --- a/src/libstd/num/i16.rs +++ b/src/libstd/num/i16.rs @@ -10,63 +10,14 @@ //! Operations and constants for signed 16-bits integers (`i16` type) -#![allow(non_uppercase_statics)] - -use prelude::*; - -use default::Default; use from_str::FromStr; -use num::{Bitwise, Bounded, CheckedAdd, CheckedSub, CheckedMul}; -use num::{CheckedDiv, Zero, One, strconv}; +use iter::Iterator; use num::{ToStrRadix, FromStrRadix}; -use option::{Option, Some, None}; +use num::strconv; +use option::Option; +use slice::{ImmutableVector, OwnedVector}; use str; -use intrinsics; - -int_module!(i16, 16) - -impl Bitwise for i16 { - /// Returns the number of ones in the binary representation of the number. - #[inline] - fn count_ones(&self) -> i16 { unsafe { intrinsics::ctpop16(*self as u16) as i16 } } - - /// Returns the number of leading zeros in the in the binary representation - /// of the number. - #[inline] - fn leading_zeros(&self) -> i16 { unsafe { intrinsics::ctlz16(*self as u16) as i16 } } - - /// Returns the number of trailing zeros in the in the binary representation - /// of the number. - #[inline] - fn trailing_zeros(&self) -> i16 { unsafe { intrinsics::cttz16(*self as u16) as i16 } } -} - -impl CheckedAdd for i16 { - #[inline] - fn checked_add(&self, v: &i16) -> Option<i16> { - unsafe { - let (x, y) = intrinsics::i16_add_with_overflow(*self, *v); - if y { None } else { Some(x) } - } - } -} -impl CheckedSub for i16 { - #[inline] - fn checked_sub(&self, v: &i16) -> Option<i16> { - unsafe { - let (x, y) = intrinsics::i16_sub_with_overflow(*self, *v); - if y { None } else { Some(x) } - } - } -} +pub use core::i16::{BITS, BYTES, MIN, MAX}; -impl CheckedMul for i16 { - #[inline] - fn checked_mul(&self, v: &i16) -> Option<i16> { - unsafe { - let (x, y) = intrinsics::i16_mul_with_overflow(*self, *v); - if y { None } else { Some(x) } - } - } -} +int_module!(i16) diff --git a/src/libstd/num/i32.rs b/src/libstd/num/i32.rs index 97f03299b87..3c3acfae3c0 100644 --- a/src/libstd/num/i32.rs +++ b/src/libstd/num/i32.rs @@ -10,63 +10,14 @@ //! Operations and constants for signed 32-bits integers (`i32` type) -#![allow(non_uppercase_statics)] - -use prelude::*; - -use default::Default; use from_str::FromStr; -use num::{Bitwise, Bounded, CheckedAdd, CheckedSub, CheckedMul}; -use num::{CheckedDiv, Zero, One, strconv}; +use iter::Iterator; use num::{ToStrRadix, FromStrRadix}; -use option::{Option, Some, None}; +use num::strconv; +use option::Option; +use slice::{ImmutableVector, OwnedVector}; use str; -use intrinsics; - -int_module!(i32, 32) - -impl Bitwise for i32 { - /// Returns the number of ones in the binary representation of the number. - #[inline] - fn count_ones(&self) -> i32 { unsafe { intrinsics::ctpop32(*self as u32) as i32 } } - - /// Returns the number of leading zeros in the in the binary representation - /// of the number. - #[inline] - fn leading_zeros(&self) -> i32 { unsafe { intrinsics::ctlz32(*self as u32) as i32 } } - - /// Returns the number of trailing zeros in the in the binary representation - /// of the number. - #[inline] - fn trailing_zeros(&self) -> i32 { unsafe { intrinsics::cttz32(*self as u32) as i32 } } -} - -impl CheckedAdd for i32 { - #[inline] - fn checked_add(&self, v: &i32) -> Option<i32> { - unsafe { - let (x, y) = intrinsics::i32_add_with_overflow(*self, *v); - if y { None } else { Some(x) } - } - } -} -impl CheckedSub for i32 { - #[inline] - fn checked_sub(&self, v: &i32) -> Option<i32> { - unsafe { - let (x, y) = intrinsics::i32_sub_with_overflow(*self, *v); - if y { None } else { Some(x) } - } - } -} +pub use core::i32::{BITS, BYTES, MIN, MAX}; -impl CheckedMul for i32 { - #[inline] - fn checked_mul(&self, v: &i32) -> Option<i32> { - unsafe { - let (x, y) = intrinsics::i32_mul_with_overflow(*self, *v); - if y { None } else { Some(x) } - } - } -} +int_module!(i32) diff --git a/src/libstd/num/i64.rs b/src/libstd/num/i64.rs index 00823aa22c2..ad0fe1c08ef 100644 --- a/src/libstd/num/i64.rs +++ b/src/libstd/num/i64.rs @@ -10,64 +10,14 @@ //! Operations and constants for signed 64-bits integers (`i64` type) -#![allow(non_uppercase_statics)] - -use prelude::*; - -use default::Default; use from_str::FromStr; -#[cfg(target_word_size = "64")] -use num::CheckedMul; -use num::{Bitwise, Bounded, CheckedAdd, CheckedSub}; -use num::{CheckedDiv, Zero, One, strconv}; +use iter::Iterator; use num::{ToStrRadix, FromStrRadix}; -use option::{Option, Some, None}; +use num::strconv; +use option::Option; +use slice::{ImmutableVector, OwnedVector}; use str; -use intrinsics; - -int_module!(i64, 64) - -impl Bitwise for i64 { - /// Returns the number of ones in the binary representation of the number. - #[inline] - fn count_ones(&self) -> i64 { unsafe { intrinsics::ctpop64(*self as u64) as i64 } } - - /// Returns the number of leading zeros in the in the binary representation - /// of the number. - #[inline] - fn leading_zeros(&self) -> i64 { unsafe { intrinsics::ctlz64(*self as u64) as i64 } } - - /// Counts the number of trailing zeros. - #[inline] - fn trailing_zeros(&self) -> i64 { unsafe { intrinsics::cttz64(*self as u64) as i64 } } -} - -impl CheckedAdd for i64 { - #[inline] - fn checked_add(&self, v: &i64) -> Option<i64> { - unsafe { - let (x, y) = intrinsics::i64_add_with_overflow(*self, *v); - if y { None } else { Some(x) } - } - } -} -impl CheckedSub for i64 { - #[inline] - fn checked_sub(&self, v: &i64) -> Option<i64> { - unsafe { - let (x, y) = intrinsics::i64_sub_with_overflow(*self, *v); - if y { None } else { Some(x) } - } - } -} +pub use core::i64::{BITS, BYTES, MIN, MAX}; -impl CheckedMul for i64 { - #[inline] - fn checked_mul(&self, v: &i64) -> Option<i64> { - unsafe { - let (x, y) = intrinsics::i64_mul_with_overflow(*self, *v); - if y { None } else { Some(x) } - } - } -} +int_module!(i64) diff --git a/src/libstd/num/i8.rs b/src/libstd/num/i8.rs index 2d349fa7f4f..bd40a2c53b6 100644 --- a/src/libstd/num/i8.rs +++ b/src/libstd/num/i8.rs @@ -10,63 +10,14 @@ //! Operations and constants for signed 8-bits integers (`i8` type) -#![allow(non_uppercase_statics)] - -use prelude::*; - -use default::Default; use from_str::FromStr; -use num::{Bitwise, Bounded, CheckedAdd, CheckedSub, CheckedMul}; -use num::{CheckedDiv, Zero, One, strconv}; +use iter::Iterator; use num::{ToStrRadix, FromStrRadix}; -use option::{Option, Some, None}; +use num::strconv; +use option::Option; +use slice::{ImmutableVector, OwnedVector}; use str; -use intrinsics; - -int_module!(i8, 8) - -impl Bitwise for i8 { - /// Returns the number of ones in the binary representation of the number. - #[inline] - fn count_ones(&self) -> i8 { unsafe { intrinsics::ctpop8(*self as u8) as i8 } } - - /// Returns the number of leading zeros in the in the binary representation - /// of the number. - #[inline] - fn leading_zeros(&self) -> i8 { unsafe { intrinsics::ctlz8(*self as u8) as i8 } } - - /// Returns the number of trailing zeros in the in the binary representation - /// of the number. - #[inline] - fn trailing_zeros(&self) -> i8 { unsafe { intrinsics::cttz8(*self as u8) as i8 } } -} - -impl CheckedAdd for i8 { - #[inline] - fn checked_add(&self, v: &i8) -> Option<i8> { - unsafe { - let (x, y) = intrinsics::i8_add_with_overflow(*self, *v); - if y { None } else { Some(x) } - } - } -} -impl CheckedSub for i8 { - #[inline] - fn checked_sub(&self, v: &i8) -> Option<i8> { - unsafe { - let (x, y) = intrinsics::i8_sub_with_overflow(*self, *v); - if y { None } else { Some(x) } - } - } -} +pub use core::i8::{BITS, BYTES, MIN, MAX}; -impl CheckedMul for i8 { - #[inline] - fn checked_mul(&self, v: &i8) -> Option<i8> { - unsafe { - let (x, y) = intrinsics::i8_mul_with_overflow(*self, *v); - if y { None } else { Some(x) } - } - } -} +int_module!(i8) diff --git a/src/libstd/num/int.rs b/src/libstd/num/int.rs index 66b204ee8bd..d9552ee3340 100644 --- a/src/libstd/num/int.rs +++ b/src/libstd/num/int.rs @@ -10,118 +10,14 @@ //! Operations and constants for architecture-sized signed integers (`int` type) -#![allow(non_uppercase_statics)] - -use prelude::*; - -use default::Default; use from_str::FromStr; -use num::{Bitwise, Bounded, CheckedAdd, CheckedSub, CheckedMul}; -use num::{CheckedDiv, Zero, One, strconv}; +use iter::Iterator; use num::{ToStrRadix, FromStrRadix}; -use option::{Option, Some, None}; +use num::strconv; +use option::Option; +use slice::{ImmutableVector, OwnedVector}; use str; -use intrinsics; - -#[cfg(target_word_size = "32")] int_module!(int, 32) -#[cfg(target_word_size = "64")] int_module!(int, 64) - -#[cfg(target_word_size = "32")] -impl Bitwise for int { - /// Returns the number of ones in the binary representation of the number. - #[inline] - fn count_ones(&self) -> int { (*self as i32).count_ones() as int } - - /// Returns the number of leading zeros in the in the binary representation - /// of the number. - #[inline] - fn leading_zeros(&self) -> int { (*self as i32).leading_zeros() as int } - - /// Returns the number of trailing zeros in the in the binary representation - /// of the number. - #[inline] - fn trailing_zeros(&self) -> int { (*self as i32).trailing_zeros() as int } -} - -#[cfg(target_word_size = "64")] -impl Bitwise for int { - /// Returns the number of ones in the binary representation of the number. - #[inline] - fn count_ones(&self) -> int { (*self as i64).count_ones() as int } - - /// Returns the number of leading zeros in the in the binary representation - /// of the number. - #[inline] - fn leading_zeros(&self) -> int { (*self as i64).leading_zeros() as int } - - /// Returns the number of trailing zeros in the in the binary representation - /// of the number. - #[inline] - fn trailing_zeros(&self) -> int { (*self as i64).trailing_zeros() as int } -} - -#[cfg(target_word_size = "32")] -impl CheckedAdd for int { - #[inline] - fn checked_add(&self, v: &int) -> Option<int> { - unsafe { - let (x, y) = intrinsics::i32_add_with_overflow(*self as i32, *v as i32); - if y { None } else { Some(x as int) } - } - } -} - -#[cfg(target_word_size = "64")] -impl CheckedAdd for int { - #[inline] - fn checked_add(&self, v: &int) -> Option<int> { - unsafe { - let (x, y) = intrinsics::i64_add_with_overflow(*self as i64, *v as i64); - if y { None } else { Some(x as int) } - } - } -} - -#[cfg(target_word_size = "32")] -impl CheckedSub for int { - #[inline] - fn checked_sub(&self, v: &int) -> Option<int> { - unsafe { - let (x, y) = intrinsics::i32_sub_with_overflow(*self as i32, *v as i32); - if y { None } else { Some(x as int) } - } - } -} - -#[cfg(target_word_size = "64")] -impl CheckedSub for int { - #[inline] - fn checked_sub(&self, v: &int) -> Option<int> { - unsafe { - let (x, y) = intrinsics::i64_sub_with_overflow(*self as i64, *v as i64); - if y { None } else { Some(x as int) } - } - } -} -#[cfg(target_word_size = "32")] -impl CheckedMul for int { - #[inline] - fn checked_mul(&self, v: &int) -> Option<int> { - unsafe { - let (x, y) = intrinsics::i32_mul_with_overflow(*self as i32, *v as i32); - if y { None } else { Some(x as int) } - } - } -} +pub use core::int::{BITS, BYTES, MIN, MAX}; -#[cfg(target_word_size = "64")] -impl CheckedMul for int { - #[inline] - fn checked_mul(&self, v: &int) -> Option<int> { - unsafe { - let (x, y) = intrinsics::i64_mul_with_overflow(*self as i64, *v as i64); - if y { None } else { Some(x as int) } - } - } -} +int_module!(int) diff --git a/src/libstd/num/int_macros.rs b/src/libstd/num/int_macros.rs index c6a9924e4ec..8a7bea46585 100644 --- a/src/libstd/num/int_macros.rs +++ b/src/libstd/num/int_macros.rs @@ -11,226 +11,7 @@ #![macro_escape] #![doc(hidden)] -macro_rules! int_module (($T:ty, $bits:expr) => ( - -// FIXME(#11621): Should be deprecated once CTFE is implemented in favour of -// calling the `mem::size_of` function. -pub static BITS : uint = $bits; -// FIXME(#11621): Should be deprecated once CTFE is implemented in favour of -// calling the `mem::size_of` function. -pub static BYTES : uint = ($bits / 8); - -// FIXME(#11621): Should be deprecated once CTFE is implemented in favour of -// calling the `Bounded::min_value` function. -pub static MIN: $T = (-1 as $T) << (BITS - 1); -// FIXME(#9837): Compute MIN like this so the high bits that shouldn't exist are 0. -// FIXME(#11621): Should be deprecated once CTFE is implemented in favour of -// calling the `Bounded::max_value` function. -pub static MAX: $T = !MIN; - -impl CheckedDiv for $T { - #[inline] - fn checked_div(&self, v: &$T) -> Option<$T> { - if *v == 0 || (*self == MIN && *v == -1) { - None - } else { - Some(self / *v) - } - } -} - -impl Num for $T {} - -#[cfg(not(test))] -impl Ord for $T { - #[inline] - fn lt(&self, other: &$T) -> bool { return (*self) < (*other); } -} - -#[cfg(not(test))] -impl Eq for $T { - #[inline] - fn eq(&self, other: &$T) -> bool { return (*self) == (*other); } -} - -impl Default for $T { - #[inline] - fn default() -> $T { 0 } -} - -impl Zero for $T { - #[inline] - fn zero() -> $T { 0 } - - #[inline] - fn is_zero(&self) -> bool { *self == 0 } -} - -impl One for $T { - #[inline] - fn one() -> $T { 1 } -} - -#[cfg(not(test))] -impl Add<$T,$T> for $T { - #[inline] - fn add(&self, other: &$T) -> $T { *self + *other } -} - -#[cfg(not(test))] -impl Sub<$T,$T> for $T { - #[inline] - fn sub(&self, other: &$T) -> $T { *self - *other } -} - -#[cfg(not(test))] -impl Mul<$T,$T> for $T { - #[inline] - fn mul(&self, other: &$T) -> $T { *self * *other } -} - -#[cfg(not(test))] -impl Div<$T,$T> for $T { - /// Integer division, truncated towards 0. - /// - /// # Examples - /// - /// ~~~ - /// assert!( 8 / 3 == 2); - /// assert!( 8 / -3 == -2); - /// assert!(-8 / 3 == -2); - /// assert!(-8 / -3 == 2); - /// - /// assert!( 1 / 2 == 0); - /// assert!( 1 / -2 == 0); - /// assert!(-1 / 2 == 0); - /// assert!(-1 / -2 == 0); - /// ~~~ - #[inline] - fn div(&self, other: &$T) -> $T { *self / *other } -} - -#[cfg(not(test))] -impl Rem<$T,$T> for $T { - /// Returns the integer remainder after division, satisfying: - /// - /// ~~~ - /// # let n = 1; - /// # let d = 2; - /// assert!((n / d) * d + (n % d) == n) - /// ~~~ - /// - /// # Examples - /// - /// ~~~ - /// assert!( 8 % 3 == 2); - /// assert!( 8 % -3 == 2); - /// assert!(-8 % 3 == -2); - /// assert!(-8 % -3 == -2); - /// - /// assert!( 1 % 2 == 1); - /// assert!( 1 % -2 == 1); - /// assert!(-1 % 2 == -1); - /// assert!(-1 % -2 == -1); - /// ~~~ - #[inline] - fn rem(&self, other: &$T) -> $T { *self % *other } -} - -#[cfg(not(test))] -impl Neg<$T> for $T { - #[inline] - fn neg(&self) -> $T { -*self } -} - -impl Signed for $T { - /// Computes the absolute value - #[inline] - fn abs(&self) -> $T { - if self.is_negative() { -*self } else { *self } - } - - /// - /// The positive difference of two numbers. Returns `0` if the number is less than or - /// equal to `other`, otherwise the difference between`self` and `other` is returned. - /// - #[inline] - fn abs_sub(&self, other: &$T) -> $T { - if *self <= *other { 0 } else { *self - *other } - } - - /// - /// # Returns - /// - /// - `0` if the number is zero - /// - `1` if the number is positive - /// - `-1` if the number is negative - /// - #[inline] - fn signum(&self) -> $T { - match *self { - n if n > 0 => 1, - 0 => 0, - _ => -1, - } - } - - /// Returns true if the number is positive - #[inline] - fn is_positive(&self) -> bool { *self > 0 } - - /// Returns true if the number is negative - #[inline] - fn is_negative(&self) -> bool { *self < 0 } -} - -#[cfg(not(test))] -impl BitOr<$T,$T> for $T { - #[inline] - fn bitor(&self, other: &$T) -> $T { *self | *other } -} - -#[cfg(not(test))] -impl BitAnd<$T,$T> for $T { - #[inline] - fn bitand(&self, other: &$T) -> $T { *self & *other } -} - -#[cfg(not(test))] -impl BitXor<$T,$T> for $T { - #[inline] - fn bitxor(&self, other: &$T) -> $T { *self ^ *other } -} - -#[cfg(not(test))] -impl Shl<$T,$T> for $T { - #[inline] - fn shl(&self, other: &$T) -> $T { *self << *other } -} - -#[cfg(not(test))] -impl Shr<$T,$T> for $T { - #[inline] - fn shr(&self, other: &$T) -> $T { *self >> *other } -} - -#[cfg(not(test))] -impl Not<$T> for $T { - #[inline] - fn not(&self) -> $T { !*self } -} - -impl Bounded for $T { - #[inline] - fn min_value() -> $T { MIN } - - #[inline] - fn max_value() -> $T { MAX } -} - -impl Int for $T {} - -impl Primitive for $T {} +macro_rules! int_module (($T:ty) => ( // String conversion functions and impl str -> num @@ -296,7 +77,7 @@ impl ToStrRadix for $T { /// Convert to a string in a given base. #[inline] fn to_str_radix(&self, radix: uint) -> ~str { - let mut buf = Vec::new(); + let mut buf = ::vec::Vec::new(); strconv::int_to_str_bytes_common(*self, radix, strconv::SignNeg, |i| { buf.push(i); }); @@ -311,90 +92,11 @@ mod tests { use prelude::*; use super::*; - use int; use i32; - use num; - use num::Bitwise; - use num::CheckedDiv; use num::ToStrRadix; use str::StrSlice; #[test] - fn test_overflows() { - assert!(MAX > 0); - assert!(MIN <= 0); - assert_eq!(MIN + MAX + 1, 0); - } - - #[test] - fn test_num() { - num::test_num(10 as $T, 2 as $T); - } - - #[test] - pub fn test_abs() { - assert_eq!((1 as $T).abs(), 1 as $T); - assert_eq!((0 as $T).abs(), 0 as $T); - assert_eq!((-1 as $T).abs(), 1 as $T); - } - - #[test] - fn test_abs_sub() { - assert_eq!((-1 as $T).abs_sub(&(1 as $T)), 0 as $T); - assert_eq!((1 as $T).abs_sub(&(1 as $T)), 0 as $T); - assert_eq!((1 as $T).abs_sub(&(0 as $T)), 1 as $T); - assert_eq!((1 as $T).abs_sub(&(-1 as $T)), 2 as $T); - } - - #[test] - fn test_signum() { - assert_eq!((1 as $T).signum(), 1 as $T); - assert_eq!((0 as $T).signum(), 0 as $T); - assert_eq!((-0 as $T).signum(), 0 as $T); - assert_eq!((-1 as $T).signum(), -1 as $T); - } - - #[test] - fn test_is_positive() { - assert!((1 as $T).is_positive()); - assert!(!(0 as $T).is_positive()); - assert!(!(-0 as $T).is_positive()); - assert!(!(-1 as $T).is_positive()); - } - - #[test] - fn test_is_negative() { - assert!(!(1 as $T).is_negative()); - assert!(!(0 as $T).is_negative()); - assert!(!(-0 as $T).is_negative()); - assert!((-1 as $T).is_negative()); - } - - #[test] - fn test_bitwise() { - assert_eq!(0b1110 as $T, (0b1100 as $T).bitor(&(0b1010 as $T))); - assert_eq!(0b1000 as $T, (0b1100 as $T).bitand(&(0b1010 as $T))); - assert_eq!(0b0110 as $T, (0b1100 as $T).bitxor(&(0b1010 as $T))); - assert_eq!(0b1110 as $T, (0b0111 as $T).shl(&(1 as $T))); - assert_eq!(0b0111 as $T, (0b1110 as $T).shr(&(1 as $T))); - assert_eq!(-(0b11 as $T) - (1 as $T), (0b11 as $T).not()); - } - - #[test] - fn test_count_ones() { - assert_eq!((0b0101100 as $T).count_ones(), 3); - assert_eq!((0b0100001 as $T).count_ones(), 2); - assert_eq!((0b1111001 as $T).count_ones(), 5); - } - - #[test] - fn test_count_zeros() { - assert_eq!((0b0101100 as $T).count_zeros(), BITS as $T - 3); - assert_eq!((0b0100001 as $T).count_zeros(), BITS as $T - 2); - assert_eq!((0b1111001 as $T).count_zeros(), BITS as $T - 5); - } - - #[test] fn test_from_str() { assert_eq!(from_str::<$T>("0"), Some(0 as $T)); assert_eq!(from_str::<$T>("3"), Some(3 as $T)); @@ -508,13 +210,6 @@ mod tests { assert_eq!(from_str::<i64>("-9223372036854775808"), Some(i64_val)); assert!(from_str::<i64>("-9223372036854775809").is_none()); } - - #[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.checked_div(&-1), None); - } } )) diff --git a/src/libstd/num/u16.rs b/src/libstd/num/u16.rs index 14a432905b4..dd6a838df9b 100644 --- a/src/libstd/num/u16.rs +++ b/src/libstd/num/u16.rs @@ -10,49 +10,14 @@ //! Operations and constants for unsigned 16-bits integers (`u16` type) -#![allow(non_uppercase_statics)] -#![allow(unsigned_negate)] - -use prelude::*; - -use default::Default; use from_str::FromStr; -use num::{Bitwise, Bounded}; -use num::{CheckedAdd, CheckedSub, CheckedMul}; -use num::{CheckedDiv, Zero, One, strconv}; +use iter::Iterator; use num::{ToStrRadix, FromStrRadix}; -use option::{Option, Some, None}; +use num::strconv; +use option::Option; +use slice::{ImmutableVector, OwnedVector}; use str; -use intrinsics; - -uint_module!(u16, i16, 16) - -impl CheckedAdd for u16 { - #[inline] - fn checked_add(&self, v: &u16) -> Option<u16> { - unsafe { - let (x, y) = intrinsics::u16_add_with_overflow(*self, *v); - if y { None } else { Some(x) } - } - } -} -impl CheckedSub for u16 { - #[inline] - fn checked_sub(&self, v: &u16) -> Option<u16> { - unsafe { - let (x, y) = intrinsics::u16_sub_with_overflow(*self, *v); - if y { None } else { Some(x) } - } - } -} +pub use core::u16::{BITS, BYTES, MIN, MAX}; -impl CheckedMul for u16 { - #[inline] - fn checked_mul(&self, v: &u16) -> Option<u16> { - unsafe { - let (x, y) = intrinsics::u16_mul_with_overflow(*self, *v); - if y { None } else { Some(x) } - } - } -} +uint_module!(u16) diff --git a/src/libstd/num/u32.rs b/src/libstd/num/u32.rs index 87740dcb135..bb05938969d 100644 --- a/src/libstd/num/u32.rs +++ b/src/libstd/num/u32.rs @@ -10,49 +10,14 @@ //! Operations and constants for unsigned 32-bits integers (`u32` type) -#![allow(non_uppercase_statics)] -#![allow(unsigned_negate)] - -use prelude::*; - -use default::Default; use from_str::FromStr; -use num::{Bitwise, Bounded}; -use num::{CheckedAdd, CheckedSub, CheckedMul}; -use num::{CheckedDiv, Zero, One, strconv}; +use iter::Iterator; use num::{ToStrRadix, FromStrRadix}; -use option::{Option, Some, None}; +use num::strconv; +use option::Option; +use slice::{ImmutableVector, OwnedVector}; use str; -use intrinsics; - -uint_module!(u32, i32, 32) - -impl CheckedAdd for u32 { - #[inline] - fn checked_add(&self, v: &u32) -> Option<u32> { - unsafe { - let (x, y) = intrinsics::u32_add_with_overflow(*self, *v); - if y { None } else { Some(x) } - } - } -} -impl CheckedSub for u32 { - #[inline] - fn checked_sub(&self, v: &u32) -> Option<u32> { - unsafe { - let (x, y) = intrinsics::u32_sub_with_overflow(*self, *v); - if y { None } else { Some(x) } - } - } -} +pub use core::u32::{BITS, BYTES, MIN, MAX}; -impl CheckedMul for u32 { - #[inline] - fn checked_mul(&self, v: &u32) -> Option<u32> { - unsafe { - let (x, y) = intrinsics::u32_mul_with_overflow(*self, *v); - if y { None } else { Some(x) } - } - } -} +uint_module!(u32) diff --git a/src/libstd/num/u64.rs b/src/libstd/num/u64.rs index 15b2528e616..f38806e1527 100644 --- a/src/libstd/num/u64.rs +++ b/src/libstd/num/u64.rs @@ -10,51 +10,14 @@ //! Operations and constants for unsigned 64-bits integer (`u64` type) -#![allow(non_uppercase_statics)] -#![allow(unsigned_negate)] - -use prelude::*; - -use default::Default; use from_str::FromStr; -use num::{Bitwise, Bounded}; -#[cfg(target_word_size = "64")] -use num::CheckedMul; -use num::{CheckedAdd, CheckedSub}; -use num::{CheckedDiv, Zero, One, strconv}; +use iter::Iterator; use num::{ToStrRadix, FromStrRadix}; -use option::{Option, Some, None}; +use num::strconv; +use option::Option; +use slice::{ImmutableVector, OwnedVector}; use str; -use intrinsics; - -uint_module!(u64, i64, 64) - -impl CheckedAdd for u64 { - #[inline] - fn checked_add(&self, v: &u64) -> Option<u64> { - unsafe { - let (x, y) = intrinsics::u64_add_with_overflow(*self, *v); - if y { None } else { Some(x) } - } - } -} -impl CheckedSub for u64 { - #[inline] - fn checked_sub(&self, v: &u64) -> Option<u64> { - unsafe { - let (x, y) = intrinsics::u64_sub_with_overflow(*self, *v); - if y { None } else { Some(x) } - } - } -} +pub use core::u64::{BITS, BYTES, MIN, MAX}; -impl CheckedMul for u64 { - #[inline] - fn checked_mul(&self, v: &u64) -> Option<u64> { - unsafe { - let (x, y) = intrinsics::u64_mul_with_overflow(*self, *v); - if y { None } else { Some(x) } - } - } -} +uint_module!(u64) diff --git a/src/libstd/num/u8.rs b/src/libstd/num/u8.rs index f841a31ee13..87fed563a15 100644 --- a/src/libstd/num/u8.rs +++ b/src/libstd/num/u8.rs @@ -10,49 +10,14 @@ //! Operations and constants for unsigned 8-bits integers (`u8` type) -#![allow(non_uppercase_statics)] -#![allow(unsigned_negate)] - -use prelude::*; - -use default::Default; use from_str::FromStr; -use num::{Bitwise, Bounded}; -use num::{CheckedAdd, CheckedSub, CheckedMul}; -use num::{CheckedDiv, Zero, One, strconv}; +use iter::Iterator; use num::{ToStrRadix, FromStrRadix}; -use option::{Option, Some, None}; +use num::strconv; +use option::Option; +use slice::{ImmutableVector, OwnedVector}; use str; -use intrinsics; - -uint_module!(u8, i8, 8) - -impl CheckedAdd for u8 { - #[inline] - fn checked_add(&self, v: &u8) -> Option<u8> { - unsafe { - let (x, y) = intrinsics::u8_add_with_overflow(*self, *v); - if y { None } else { Some(x) } - } - } -} -impl CheckedSub for u8 { - #[inline] - fn checked_sub(&self, v: &u8) -> Option<u8> { - unsafe { - let (x, y) = intrinsics::u8_sub_with_overflow(*self, *v); - if y { None } else { Some(x) } - } - } -} +pub use core::u8::{BITS, BYTES, MIN, MAX}; -impl CheckedMul for u8 { - #[inline] - fn checked_mul(&self, v: &u8) -> Option<u8> { - unsafe { - let (x, y) = intrinsics::u8_mul_with_overflow(*self, *v); - if y { None } else { Some(x) } - } - } -} +uint_module!(u8) diff --git a/src/libstd/num/uint.rs b/src/libstd/num/uint.rs index 46cb4f44887..61ab97e86b8 100644 --- a/src/libstd/num/uint.rs +++ b/src/libstd/num/uint.rs @@ -10,85 +10,14 @@ //! Operations and constants for architecture-sized unsigned integers (`uint` type) -#![allow(non_uppercase_statics)] -#![allow(unsigned_negate)] - -use prelude::*; - -use default::Default; use from_str::FromStr; -use num::{Bitwise, Bounded}; -use num::{CheckedAdd, CheckedSub, CheckedMul}; -use num::{CheckedDiv, Zero, One, strconv}; +use iter::Iterator; use num::{ToStrRadix, FromStrRadix}; -use option::{Option, Some, None}; +use num::strconv; +use option::Option; +use slice::{ImmutableVector, OwnedVector}; use str; -use intrinsics; - -uint_module!(uint, int, ::int::BITS) - -#[cfg(target_word_size = "32")] -impl CheckedAdd for uint { - #[inline] - fn checked_add(&self, v: &uint) -> Option<uint> { - unsafe { - let (x, y) = intrinsics::u32_add_with_overflow(*self as u32, *v as u32); - if y { None } else { Some(x as uint) } - } - } -} - -#[cfg(target_word_size = "64")] -impl CheckedAdd for uint { - #[inline] - fn checked_add(&self, v: &uint) -> Option<uint> { - unsafe { - let (x, y) = intrinsics::u64_add_with_overflow(*self as u64, *v as u64); - if y { None } else { Some(x as uint) } - } - } -} - -#[cfg(target_word_size = "32")] -impl CheckedSub for uint { - #[inline] - fn checked_sub(&self, v: &uint) -> Option<uint> { - unsafe { - let (x, y) = intrinsics::u32_sub_with_overflow(*self as u32, *v as u32); - if y { None } else { Some(x as uint) } - } - } -} - -#[cfg(target_word_size = "64")] -impl CheckedSub for uint { - #[inline] - fn checked_sub(&self, v: &uint) -> Option<uint> { - unsafe { - let (x, y) = intrinsics::u64_sub_with_overflow(*self as u64, *v as u64); - if y { None } else { Some(x as uint) } - } - } -} -#[cfg(target_word_size = "32")] -impl CheckedMul for uint { - #[inline] - fn checked_mul(&self, v: &uint) -> Option<uint> { - unsafe { - let (x, y) = intrinsics::u32_mul_with_overflow(*self as u32, *v as u32); - if y { None } else { Some(x as uint) } - } - } -} +pub use core::uint::{BITS, BYTES, MIN, MAX}; -#[cfg(target_word_size = "64")] -impl CheckedMul for uint { - #[inline] - fn checked_mul(&self, v: &uint) -> Option<uint> { - unsafe { - let (x, y) = intrinsics::u64_mul_with_overflow(*self as u64, *v as u64); - if y { None } else { Some(x as uint) } - } - } -} +uint_module!(uint) diff --git a/src/libstd/num/uint_macros.rs b/src/libstd/num/uint_macros.rs index fac8736b929..3e64c171613 100644 --- a/src/libstd/num/uint_macros.rs +++ b/src/libstd/num/uint_macros.rs @@ -12,140 +12,7 @@ #![doc(hidden)] #![allow(unsigned_negate)] -macro_rules! uint_module (($T:ty, $T_SIGNED:ty, $bits:expr) => ( - -pub static BITS : uint = $bits; -pub static BYTES : uint = ($bits / 8); - -pub static MIN: $T = 0 as $T; -pub static MAX: $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) - } - } -} - -impl Num for $T {} - -#[cfg(not(test))] -impl Ord for $T { - #[inline] - fn lt(&self, other: &$T) -> bool { (*self) < (*other) } -} - -#[cfg(not(test))] -impl Eq for $T { - #[inline] - fn eq(&self, other: &$T) -> bool { return (*self) == (*other); } -} - -impl Default for $T { - #[inline] - fn default() -> $T { 0 } -} - -impl Zero for $T { - #[inline] - fn zero() -> $T { 0 } - - #[inline] - fn is_zero(&self) -> bool { *self == 0 } -} - -impl One for $T { - #[inline] - fn one() -> $T { 1 } -} - -#[cfg(not(test))] -impl Add<$T,$T> for $T { - #[inline] - fn add(&self, other: &$T) -> $T { *self + *other } -} - -#[cfg(not(test))] -impl Sub<$T,$T> for $T { - #[inline] - fn sub(&self, other: &$T) -> $T { *self - *other } -} - -#[cfg(not(test))] -impl Mul<$T,$T> for $T { - #[inline] - fn mul(&self, other: &$T) -> $T { *self * *other } -} - -#[cfg(not(test))] -impl Div<$T,$T> for $T { - #[inline] - fn div(&self, other: &$T) -> $T { *self / *other } -} - -#[cfg(not(test))] -impl Rem<$T,$T> for $T { - #[inline] - fn rem(&self, other: &$T) -> $T { *self % *other } -} - -#[cfg(not(test))] -impl Neg<$T> for $T { - #[inline] - fn neg(&self) -> $T { -*self } -} - -impl Unsigned for $T {} - -#[cfg(not(test))] -impl BitOr<$T,$T> for $T { - #[inline] - fn bitor(&self, other: &$T) -> $T { *self | *other } -} - -#[cfg(not(test))] -impl BitAnd<$T,$T> for $T { - #[inline] - fn bitand(&self, other: &$T) -> $T { *self & *other } -} - -#[cfg(not(test))] -impl BitXor<$T,$T> for $T { - #[inline] - fn bitxor(&self, other: &$T) -> $T { *self ^ *other } -} - -#[cfg(not(test))] -impl Shl<$T,$T> for $T { - #[inline] - fn shl(&self, other: &$T) -> $T { *self << *other } -} - -#[cfg(not(test))] -impl Shr<$T,$T> for $T { - #[inline] - fn shr(&self, other: &$T) -> $T { *self >> *other } -} - -#[cfg(not(test))] -impl Not<$T> for $T { - #[inline] - fn not(&self) -> $T { !*self } -} - -impl Bounded for $T { - #[inline] - fn min_value() -> $T { MIN } - - #[inline] - fn max_value() -> $T { MAX } -} - -impl Int for $T {} +macro_rules! uint_module (($T:ty) => ( // String conversion functions and impl str -> num @@ -211,7 +78,7 @@ impl ToStrRadix for $T { /// Convert to a string in a given base. #[inline] fn to_str_radix(&self, radix: uint) -> ~str { - let mut buf = Vec::new(); + let mut buf = ::vec::Vec::new(); strconv::int_to_str_bytes_common(*self, radix, strconv::SignNone, |i| { buf.push(i); }); @@ -221,79 +88,16 @@ impl ToStrRadix for $T { } } -impl Primitive for $T {} - -impl Bitwise for $T { - /// Returns the number of ones in the binary representation of the number. - #[inline] - fn count_ones(&self) -> $T { - (*self as $T_SIGNED).count_ones() as $T - } - - /// Returns the number of leading zeros in the in the binary representation - /// of the number. - #[inline] - fn leading_zeros(&self) -> $T { - (*self as $T_SIGNED).leading_zeros() as $T - } - - /// Returns the number of trailing zeros in the in the binary representation - /// of the number. - #[inline] - fn trailing_zeros(&self) -> $T { - (*self as $T_SIGNED).trailing_zeros() as $T - } -} - #[cfg(test)] mod tests { use prelude::*; use super::*; - use num; - use num::CheckedDiv; - use num::Bitwise; use num::ToStrRadix; use str::StrSlice; use u16; #[test] - fn test_overflows() { - assert!(MAX > 0); - assert!(MIN <= 0); - assert_eq!(MIN + MAX + 1, 0); - } - - #[test] - fn test_num() { - num::test_num(10 as $T, 2 as $T); - } - - #[test] - fn test_bitwise() { - assert_eq!(0b1110 as $T, (0b1100 as $T).bitor(&(0b1010 as $T))); - assert_eq!(0b1000 as $T, (0b1100 as $T).bitand(&(0b1010 as $T))); - assert_eq!(0b0110 as $T, (0b1100 as $T).bitxor(&(0b1010 as $T))); - assert_eq!(0b1110 as $T, (0b0111 as $T).shl(&(1 as $T))); - assert_eq!(0b0111 as $T, (0b1110 as $T).shr(&(1 as $T))); - assert_eq!(MAX - (0b1011 as $T), (0b1011 as $T).not()); - } - - #[test] - fn test_count_ones() { - assert_eq!((0b0101100 as $T).count_ones(), 3); - assert_eq!((0b0100001 as $T).count_ones(), 2); - assert_eq!((0b1111001 as $T).count_ones(), 5); - } - - #[test] - fn test_count_zeros() { - assert_eq!((0b0101100 as $T).count_zeros(), BITS as $T - 3); - assert_eq!((0b0100001 as $T).count_zeros(), BITS as $T - 2); - assert_eq!((0b1111001 as $T).count_zeros(), BITS as $T - 5); - } - - #[test] pub fn test_to_str() { assert_eq!((0 as $T).to_str_radix(10u), "0".to_owned()); assert_eq!((1 as $T).to_str_radix(10u), "1".to_owned()); @@ -404,12 +208,6 @@ mod tests { pub fn to_str_radix37() { 100u.to_str_radix(37u); } - - #[test] - fn test_unsigned_checked_div() { - assert_eq!(10u.checked_div(&2), Some(5)); - assert_eq!(5u.checked_div(&0), None); - } } )) |
