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.
This commit is contained in:
Alex Crichton 2014-04-30 22:23:26 -07:00
parent 0c30293886
commit be0a11729e
30 changed files with 1825 additions and 1506 deletions

View File

@ -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 */

224
src/libcore/num/f32.rs Normal file
View File

@ -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 }
}

224
src/libcore/num/f64.rs Normal file
View File

@ -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 }
}

View File

@ -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);
})
)

68
src/libcore/num/i16.rs Normal file
View File

@ -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) }
}
}
}

68
src/libcore/num/i32.rs Normal file
View File

@ -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) }
}
}
}

67
src/libcore/num/i64.rs Normal file
View File

@ -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) }
}
}
}

68
src/libcore/num/i8.rs Normal file
View File

@ -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) }
}
}
}

123
src/libcore/num/int.rs Normal file
View File

@ -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) }
}
}
}

View File

@ -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);
}
}
))

52
src/libcore/num/u16.rs Normal file
View File

@ -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) }
}
}
}

52
src/libcore/num/u32.rs Normal file
View File

@ -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) }
}
}
}

52
src/libcore/num/u64.rs Normal file
View File

@ -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) }
}
}
}

52
src/libcore/num/u8.rs Normal file
View File

@ -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) }
}
}
}

88
src/libcore/num/uint.rs Normal file
View File

@ -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) }
}
}
}

View File

@ -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);
}
}
))

View File

@ -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 }

View File

@ -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 }

View File

@ -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)
pub use core::i16::{BITS, BYTES, MIN, MAX};
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) }
}
}
}
int_module!(i16)

View File

@ -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)
pub use core::i32::{BITS, BYTES, MIN, MAX};
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) }
}
}
}
int_module!(i32)

View File

@ -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)
pub use core::i64::{BITS, BYTES, MIN, MAX};
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) }
}
}
}
int_module!(i64)

View File

@ -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)
pub use core::i8::{BITS, BYTES, MIN, MAX};
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) }
}
}
}
int_module!(i8)

View File

@ -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)
pub use core::int::{BITS, BYTES, MIN, MAX};
#[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) }
}
}
}
int_module!(int)

View File

@ -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,89 +92,10 @@ 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));
@ -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);
}
}
))

View File

@ -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)
pub use core::u16::{BITS, BYTES, MIN, MAX};
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) }
}
}
}
uint_module!(u16)

View File

@ -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)
pub use core::u32::{BITS, BYTES, MIN, MAX};
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) }
}
}
}
uint_module!(u32)

View File

@ -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)
pub use core::u64::{BITS, BYTES, MIN, MAX};
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) }
}
}
}
uint_module!(u64)

View File

@ -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)
pub use core::u8::{BITS, BYTES, MIN, MAX};
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) }
}
}
}
uint_module!(u8)

View File

@ -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)
pub use core::uint::{BITS, BYTES, MIN, MAX};
#[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) }
}
}
}
uint_module!(uint)

View File

@ -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,78 +88,15 @@ 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());
@ -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);
}
}
))