diff --git a/src/doc/guide-lifetimes.md b/src/doc/guide-lifetimes.md index b6ea1ddb3949d..e3c050f0e9016 100644 --- a/src/doc/guide-lifetimes.md +++ b/src/doc/guide-lifetimes.md @@ -51,6 +51,7 @@ expensive. So we'd like to define a function that takes the points just as a reference. ~~~ +# use std::num::Float; # struct Point {x: f64, y: f64} # fn sqrt(f: f64) -> f64 { 0.0 } fn compute_distance(p1: &Point, p2: &Point) -> f64 { diff --git a/src/doc/guide-tasks.md b/src/doc/guide-tasks.md index 4eaca64560ca2..c2309ba479ea6 100644 --- a/src/doc/guide-tasks.md +++ b/src/doc/guide-tasks.md @@ -225,6 +225,7 @@ Here is another example showing how futures allow you to background computations. The workload will be distributed on the available cores. ```{rust} +# use std::num::Float; # use std::sync::Future; fn partial_sum(start: uint) -> f64 { let mut local_sum = 0f64; @@ -262,6 +263,7 @@ several computations on a single large vector of floats. Each task needs the full vector to perform its duty. ```{rust} +use std::num::Float; use std::rand; use std::sync::Arc; diff --git a/src/etc/vim/syntax/rust.vim b/src/etc/vim/syntax/rust.vim index 0ef9734cf2e99..710092a3e5f37 100644 --- a/src/etc/vim/syntax/rust.vim +++ b/src/etc/vim/syntax/rust.vim @@ -97,8 +97,7 @@ syn keyword rustTrait FromIterator IntoIterator Extend ExactSize syn keyword rustTrait Iterator DoubleEndedIterator syn keyword rustTrait RandomAccessIterator CloneableIterator syn keyword rustTrait OrdIterator MutableDoubleEndedIterator -syn keyword rustTrait Num NumCast CheckedAdd CheckedSub CheckedMul CheckedDiv -syn keyword rustTrait Signed Unsigned Primitive Int Float +syn keyword rustTrait NumCast Int SignedInt UnsignedInt Float syn keyword rustTrait FloatMath ToPrimitive FromPrimitive syn keyword rustTrait Box syn keyword rustTrait GenericPath Path PosixPath WindowsPath diff --git a/src/libarena/lib.rs b/src/libarena/lib.rs index 3e93430eb6937..33d4406b733c1 100644 --- a/src/libarena/lib.rs +++ b/src/libarena/lib.rs @@ -38,7 +38,7 @@ use std::cmp; use std::intrinsics::{TyDesc, get_tydesc}; use std::intrinsics; use std::mem; -use std::num; +use std::num::{Int, UnsignedInt}; use std::ptr; use std::rc::Rc; use std::rt::heap::{allocate, deallocate}; @@ -132,7 +132,7 @@ impl Drop for Arena { #[inline] fn round_up(base: uint, align: uint) -> uint { - (base.checked_add(&(align - 1))).unwrap() & !(align - 1) + (base.checked_add(align - 1)).unwrap() & !(align - 1) } // Walk down a chunk, running the destructors for any objects stored @@ -187,7 +187,7 @@ impl Arena { self.chunks.borrow_mut().push(self.copy_head.borrow().clone()); *self.copy_head.borrow_mut() = - chunk(num::next_power_of_two(new_min_chunk_size + 1u), true); + chunk((new_min_chunk_size + 1u).next_power_of_two(), true); return self.alloc_copy_inner(n_bytes, align); } @@ -228,7 +228,7 @@ impl Arena { self.chunks.borrow_mut().push(self.head.borrow().clone()); *self.head.borrow_mut() = - chunk(num::next_power_of_two(new_min_chunk_size + 1u), false); + chunk((new_min_chunk_size + 1u).next_power_of_two(), false); return self.alloc_noncopy_inner(n_bytes, align); } @@ -376,8 +376,8 @@ fn calculate_size(capacity: uint) -> uint { let mut size = mem::size_of::>(); size = round_up(size, mem::min_align_of::()); let elem_size = mem::size_of::(); - let elems_size = elem_size.checked_mul(&capacity).unwrap(); - size = size.checked_add(&elems_size).unwrap(); + let elems_size = elem_size.checked_mul(capacity).unwrap(); + size = size.checked_add(elems_size).unwrap(); size } @@ -432,7 +432,7 @@ impl TypedArenaChunk { #[inline] fn end(&self) -> *const u8 { unsafe { - let size = mem::size_of::().checked_mul(&self.capacity).unwrap(); + let size = mem::size_of::().checked_mul(self.capacity).unwrap(); self.start().offset(size as int) } } @@ -481,7 +481,7 @@ impl TypedArena { fn grow(&self) { unsafe { let chunk = *self.first.borrow_mut(); - let new_capacity = (*chunk).capacity.checked_mul(&2).unwrap(); + let new_capacity = (*chunk).capacity.checked_mul(2).unwrap(); let chunk = TypedArenaChunk::::new(chunk, new_capacity); self.ptr.set((*chunk).start() as *const T); self.end.set((*chunk).end() as *const T); diff --git a/src/libcollections/bit.rs b/src/libcollections/bit.rs index 6ed9dad6252da..bfb5a010ed80d 100644 --- a/src/libcollections/bit.rs +++ b/src/libcollections/bit.rs @@ -22,6 +22,7 @@ //! //! ``` //! use std::collections::{BitvSet, Bitv}; +//! use std::num::Float; //! use std::iter; //! //! let max_prime = 10000; @@ -69,6 +70,7 @@ use core::default::Default; use core::fmt; use core::iter::{Chain, Enumerate, Repeat, Skip, Take}; use core::iter; +use core::num::Int; use core::slice; use core::u32; use std::hash; diff --git a/src/libcollections/enum_set.rs b/src/libcollections/enum_set.rs index cc8581037649d..ac8e45f9f9417 100644 --- a/src/libcollections/enum_set.rs +++ b/src/libcollections/enum_set.rs @@ -15,6 +15,7 @@ use core::prelude::*; use core::fmt; +use core::num::Int; // FIXME(contentions): implement union family of methods? (general design may be wrong here) diff --git a/src/libcollections/hash/mod.rs b/src/libcollections/hash/mod.rs index 43faaac39523c..6082a0ca0137c 100644 --- a/src/libcollections/hash/mod.rs +++ b/src/libcollections/hash/mod.rs @@ -69,6 +69,7 @@ use alloc::boxed::Box; use alloc::rc::Rc; use core::intrinsics::TypeId; use core::mem; +use core::num::Int; use vec::Vec; diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs index 0e3799ed9ac37..4fad6081a9348 100644 --- a/src/libcollections/vec.rs +++ b/src/libcollections/vec.rs @@ -21,7 +21,7 @@ use core::default::Default; use core::fmt; use core::kinds::marker::{ContravariantLifetime, InvariantType}; use core::mem; -use core::num; +use core::num::{Int, UnsignedInt}; use core::ops; use core::ptr; use core::raw::Slice as RawSlice; @@ -161,7 +161,7 @@ impl Vec { } else if capacity == 0 { Vec::new() } else { - let size = capacity.checked_mul(&mem::size_of::()) + let size = capacity.checked_mul(mem::size_of::()) .expect("capacity overflow"); let ptr = unsafe { allocate(size, mem::min_align_of::()) }; Vec { ptr: ptr as *mut T, len: 0, cap: capacity } @@ -601,11 +601,11 @@ impl Vec { #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn reserve(&mut self, additional: uint) { if self.cap - self.len < additional { - match self.len.checked_add(&additional) { + match self.len.checked_add(additional) { None => panic!("Vec::reserve: `uint` overflow"), // if the checked_add Some(new_cap) => { - let amort_cap = num::next_power_of_two(new_cap); + let amort_cap = new_cap.next_power_of_two(); // next_power_of_two will overflow to exactly 0 for really big capacities if amort_cap == 0 { self.grow_capacity(new_cap); @@ -638,7 +638,7 @@ impl Vec { #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn reserve_exact(&mut self, additional: uint) { if self.cap - self.len < additional { - match self.len.checked_add(&additional) { + match self.len.checked_add(additional) { None => panic!("Vec::reserve: `uint` overflow"), Some(new_cap) => self.grow_capacity(new_cap) } @@ -971,7 +971,7 @@ impl Vec { pub fn push(&mut self, value: T) { if mem::size_of::() == 0 { // zero-size types consume no memory, so we can't rely on the address space running out - self.len = self.len.checked_add(&1).expect("length overflow"); + self.len = self.len.checked_add(1).expect("length overflow"); unsafe { mem::forget(value); } return } @@ -1064,7 +1064,7 @@ impl Vec { if mem::size_of::() == 0 { return } if capacity > self.cap { - let size = capacity.checked_mul(&mem::size_of::()) + let size = capacity.checked_mul(mem::size_of::()) .expect("capacity overflow"); unsafe { self.ptr = alloc_or_realloc(self.ptr, self.cap * mem::size_of::(), size); diff --git a/src/libcore/cmp.rs b/src/libcore/cmp.rs index 6e87fe4ced02d..ec339d10e4bb9 100644 --- a/src/libcore/cmp.rs +++ b/src/libcore/cmp.rs @@ -19,6 +19,8 @@ //! operators, you could do the following: //! //! ```rust +//! use core::num::SignedInt; +//! //! // Our type. //! struct SketchyNum { //! num : int diff --git a/src/libcore/fmt/float.rs b/src/libcore/fmt/float.rs index a6e5b0cff5592..ec920ddc6dbc5 100644 --- a/src/libcore/fmt/float.rs +++ b/src/libcore/fmt/float.rs @@ -13,8 +13,8 @@ use char; use fmt; use iter::{range, DoubleEndedIterator}; -use num::{Float, FPNaN, FPInfinite, ToPrimitive, Primitive}; -use num::{Zero, One, cast}; +use num::{Float, FPNaN, FPInfinite, ToPrimitive}; +use num::cast; use result::Ok; use slice::{mod, SlicePrelude}; use str::StrPrelude; @@ -79,7 +79,7 @@ static DIGIT_E_RADIX: uint = ('e' as uint) - ('a' as uint) + 11u; * - Fails if `radix` > 25 and `exp_format` is `ExpBin` due to conflict * between digit and exponent sign `'p'`. */ -pub fn float_to_str_bytes_common( +pub fn float_to_str_bytes_common( num: T, radix: uint, negative_zero: bool, @@ -97,8 +97,8 @@ pub fn float_to_str_bytes_common( _ => () } - let _0: T = Zero::zero(); - let _1: T = One::one(); + let _0: T = Float::zero(); + let _1: T = Float::one(); match num.classify() { FPNaN => return f("NaN".as_bytes()), diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs index 081f373b8310c..380ca82783adb 100644 --- a/src/libcore/fmt/mod.rs +++ b/src/libcore/fmt/mod.rs @@ -620,7 +620,7 @@ impl<'a, T> Pointer for &'a mut T { macro_rules! floating(($ty:ident) => { impl Float for $ty { fn fmt(&self, fmt: &mut Formatter) -> Result { - use num::{Float, Signed}; + use num::Float; let digits = match fmt.precision { Some(i) => float::DigExact(i), @@ -641,7 +641,7 @@ macro_rules! floating(($ty:ident) => { impl LowerExp for $ty { fn fmt(&self, fmt: &mut Formatter) -> Result { - use num::{Float, Signed}; + use num::Float; let digits = match fmt.precision { Some(i) => float::DigExact(i), @@ -662,7 +662,7 @@ macro_rules! floating(($ty:ident) => { impl UpperExp for $ty { fn fmt(&self, fmt: &mut Formatter) -> Result { - use num::{Float, Signed}; + use num::Float; let digits = match fmt.precision { Some(i) => float::DigExact(i), diff --git a/src/libcore/fmt/num.rs b/src/libcore/fmt/num.rs index e4a6c1a97584f..0a5af56217c8d 100644 --- a/src/libcore/fmt/num.rs +++ b/src/libcore/fmt/num.rs @@ -16,7 +16,7 @@ use fmt; use iter::DoubleEndedIterator; -use num::{Int, cast, zero}; +use num::{Int, cast}; use slice::SlicePrelude; /// A type that represents a specific radix @@ -35,10 +35,11 @@ trait GenericRadix { fn fmt_int(&self, mut x: T, f: &mut fmt::Formatter) -> fmt::Result { // The radix can be as low as 2, so we need a buffer of at least 64 // characters for a base 2 number. + let zero = Int::zero(); + let is_positive = x >= zero; let mut buf = [0u8, ..64]; - let base = cast(self.base()).unwrap(); let mut curr = buf.len(); - let is_positive = x >= zero(); + let base = cast(self.base()).unwrap(); if is_positive { // Accumulate each digit of the number from the least significant // to the most significant figure. @@ -47,16 +48,16 @@ trait GenericRadix { x = x / base; // Deaccumulate the number. *byte = self.digit(cast(n).unwrap()); // Store the digit in the buffer. curr -= 1; - if x == zero() { break; } // No more digits left to accumulate. + if x == zero { break }; // No more digits left to accumulate. } } else { // Do the same as above, but accounting for two's complement. for byte in buf.iter_mut().rev() { - let n = -(x % base); // Get the current place value. + let n = zero - (x % base); // Get the current place value. x = x / base; // Deaccumulate the number. *byte = self.digit(cast(n).unwrap()); // Store the digit in the buffer. curr -= 1; - if x == zero() { break; } // No more digits left to accumulate. + if x == zero { break }; // No more digits left to accumulate. } } f.pad_integral(is_positive, self.prefix(), buf[curr..]) diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs index a717d3c2c993d..774aa8a66d288 100644 --- a/src/libcore/iter.rs +++ b/src/libcore/iter.rs @@ -60,10 +60,10 @@ This `for` loop syntax can be applied to any iterator over any type. use clone::Clone; use cmp; -use cmp::{PartialEq, PartialOrd, Ord}; +use cmp::Ord; use mem; -use num::{Zero, One, CheckedAdd, CheckedSub, Saturating, ToPrimitive, Int}; -use ops::{Add, Mul, Sub}; +use num::{ToPrimitive, Int}; +use ops::Add; use option::{Option, Some, None}; use uint; #[deprecated = "renamed to Extend"] pub use self::Extend as Extendable; @@ -573,6 +573,8 @@ pub trait Iterator { /// # Example /// /// ```rust + /// use core::num::SignedInt; + /// /// let xs = [-3i, 0, 1, 5, -10]; /// assert_eq!(*xs.iter().max_by(|x| x.abs()).unwrap(), -10); /// ``` @@ -597,6 +599,8 @@ pub trait Iterator { /// # Example /// /// ```rust + /// use core::num::SignedInt; + /// /// let xs = [-3i, 0, 1, 5, -10]; /// assert_eq!(*xs.iter().min_by(|x| x.abs()).unwrap(), 0); /// ``` @@ -785,13 +789,28 @@ pub trait AdditiveIterator { fn sum(&mut self) -> A; } -impl + Zero, T: Iterator> AdditiveIterator for T { - #[inline] - fn sum(&mut self) -> A { - let zero: A = Zero::zero(); - self.fold(zero, |s, x| s + x) - } -} +macro_rules! impl_additive { + ($A:ty, $init:expr) => { + impl> AdditiveIterator<$A> for T { + #[inline] + fn sum(&mut self) -> $A { + self.fold($init, |acc, x| acc + x) + } + } + }; +} +impl_additive!(i8, 0) +impl_additive!(i16, 0) +impl_additive!(i32, 0) +impl_additive!(i64, 0) +impl_additive!(int, 0) +impl_additive!(u8, 0) +impl_additive!(u16, 0) +impl_additive!(u32, 0) +impl_additive!(u64, 0) +impl_additive!(uint, 0) +impl_additive!(f32, 0.0) +impl_additive!(f64, 0.0) /// A trait for iterators over elements which can be multiplied together. pub trait MultiplicativeIterator { @@ -812,13 +831,28 @@ pub trait MultiplicativeIterator { fn product(&mut self) -> A; } -impl + One, T: Iterator> MultiplicativeIterator for T { - #[inline] - fn product(&mut self) -> A { - let one: A = One::one(); - self.fold(one, |p, x| p * x) - } -} +macro_rules! impl_multiplicative { + ($A:ty, $init:expr) => { + impl> MultiplicativeIterator<$A> for T { + #[inline] + fn product(&mut self) -> $A { + self.fold($init, |acc, x| acc * x) + } + } + }; +} +impl_multiplicative!(i8, 1) +impl_multiplicative!(i16, 1) +impl_multiplicative!(i32, 1) +impl_multiplicative!(i64, 1) +impl_multiplicative!(int, 1) +impl_multiplicative!(u8, 1) +impl_multiplicative!(u16, 1) +impl_multiplicative!(u32, 1) +impl_multiplicative!(u64, 1) +impl_multiplicative!(uint, 1) +impl_multiplicative!(f32, 1.0) +impl_multiplicative!(f64, 1.0) /// A trait for iterators over elements which can be compared to one another. pub trait OrdIterator { @@ -1093,7 +1127,7 @@ impl, U: Iterator> Iterator for Chain { let lower = a_lower.saturating_add(b_lower); let upper = match (a_upper, b_upper) { - (Some(x), Some(y)) => x.checked_add(&y), + (Some(x), Some(y)) => x.checked_add(y), _ => None }; @@ -1415,7 +1449,7 @@ impl> Iterator for Peekable { if self.peeked.is_some() { let lo = lo.saturating_add(1); let hi = match hi { - Some(x) => x.checked_add(&1), + Some(x) => x.checked_add(1), None => None }; (lo, hi) @@ -1680,7 +1714,7 @@ impl<'a, A, T: Iterator, B, U: Iterator> Iterator for FlatMap<'a, A, T, let (blo, bhi) = self.backiter.as_ref().map_or((0, Some(0)), |it| it.size_hint()); let lo = flo.saturating_add(blo); match (self.iter.size_hint(), fhi, bhi) { - ((0, Some(0)), Some(a), Some(b)) => (lo, a.checked_add(&b)), + ((0, Some(0)), Some(a), Some(b)) => (lo, a.checked_add(b)), _ => (lo, None) } } @@ -1905,7 +1939,7 @@ impl + Clone> Iterator for Counter { pub struct Range { state: A, stop: A, - one: A + one: A, } /// Returns an iterator over the given range [start, stop) (that is, starting @@ -1922,12 +1956,16 @@ pub struct Range { /// } /// ``` #[inline] -pub fn range + PartialOrd + Clone + One>(start: A, stop: A) -> Range { - Range{state: start, stop: stop, one: One::one()} +pub fn range(start: A, stop: A) -> Range { + Range { + state: start, + stop: stop, + one: Int::one(), + } } // FIXME: #10414: Unfortunate type bound -impl + PartialOrd + Clone + ToPrimitive> Iterator for Range { +impl Iterator for Range { #[inline] fn next(&mut self) -> Option { if self.state < self.stop { @@ -1946,7 +1984,7 @@ impl + PartialOrd + Clone + ToPrimitive> Iterator for Range { // the i64/u64 might lie within their range. let bound = match self.state.to_i64() { Some(a) => { - let sz = self.stop.to_i64().map(|b| b.checked_sub(&a)); + let sz = self.stop.to_i64().map(|b| b.checked_sub(a)); match sz { Some(Some(bound)) => bound.to_uint(), _ => None, @@ -1954,7 +1992,7 @@ impl + PartialOrd + Clone + ToPrimitive> Iterator for Range { }, None => match self.state.to_u64() { Some(a) => { - let sz = self.stop.to_u64().map(|b| b.checked_sub(&a)); + let sz = self.stop.to_u64().map(|b| b.checked_sub(a)); match sz { Some(Some(bound)) => bound.to_uint(), _ => None @@ -1974,7 +2012,7 @@ impl + PartialOrd + Clone + ToPrimitive> Iterator for Range { /// `Int` is required to ensure the range will be the same regardless of /// the direction it is consumed. -impl DoubleEndedIterator for Range { +impl DoubleEndedIterator for Range { #[inline] fn next_back(&mut self) -> Option { if self.stop > self.state { @@ -1995,12 +2033,14 @@ pub struct RangeInclusive { /// Return an iterator over the range [start, stop] #[inline] -pub fn range_inclusive + PartialOrd + Clone + One>(start: A, stop: A) - -> RangeInclusive { - RangeInclusive{range: range(start, stop), done: false} +pub fn range_inclusive(start: A, stop: A) -> RangeInclusive { + RangeInclusive { + range: range(start, stop), + done: false, + } } -impl + PartialOrd + Clone + ToPrimitive> Iterator for RangeInclusive { +impl Iterator for RangeInclusive { #[inline] fn next(&mut self) -> Option { match self.range.next() { @@ -2024,7 +2064,7 @@ impl + PartialOrd + Clone + ToPrimitive> Iterator for RangeInclu } else { let lo = lo.saturating_add(1); let hi = match hi { - Some(x) => x.checked_add(&1), + Some(x) => x.checked_add(1), None => None }; (lo, hi) @@ -2032,8 +2072,7 @@ impl + PartialOrd + Clone + ToPrimitive> Iterator for RangeInclu } } -impl + Int + PartialOrd + Clone + ToPrimitive> DoubleEndedIterator - for RangeInclusive { +impl DoubleEndedIterator for RangeInclusive { #[inline] fn next_back(&mut self) -> Option { if self.range.stop > self.range.state { @@ -2060,18 +2099,17 @@ pub struct RangeStep { /// Return an iterator over the range [start, stop) by `step`. It handles overflow by stopping. #[inline] -pub fn range_step(start: A, stop: A, step: A) -> RangeStep { - let rev = step < Zero::zero(); +pub fn range_step(start: A, stop: A, step: A) -> RangeStep { + let rev = step < Int::zero(); RangeStep{state: start, stop: stop, step: step, rev: rev} } -impl Iterator for RangeStep { +impl Iterator for RangeStep { #[inline] fn next(&mut self) -> Option { if (self.rev && self.state > self.stop) || (!self.rev && self.state < self.stop) { - let result = self.state.clone(); - match self.state.checked_add(&self.step) { + let result = self.state; + match self.state.checked_add(self.step) { Some(x) => self.state = x, None => self.state = self.stop.clone() } @@ -2094,19 +2132,24 @@ pub struct RangeStepInclusive { /// Return an iterator over the range [start, stop] by `step`. It handles overflow by stopping. #[inline] -pub fn range_step_inclusive(start: A, stop: A, - step: A) -> RangeStepInclusive { - let rev = step < Zero::zero(); - RangeStepInclusive{state: start, stop: stop, step: step, rev: rev, done: false} +pub fn range_step_inclusive(start: A, stop: A, step: A) -> RangeStepInclusive { + let rev = step < Int::zero(); + RangeStepInclusive { + state: start, + stop: stop, + step: step, + rev: rev, + done: false, + } } -impl Iterator for RangeStepInclusive { +impl Iterator for RangeStepInclusive { #[inline] fn next(&mut self) -> Option { if !self.done && ((self.rev && self.state >= self.stop) || (!self.rev && self.state <= self.stop)) { - let result = self.state.clone(); - match self.state.checked_add(&self.step) { + let result = self.state; + match self.state.checked_add(self.step) { Some(x) => self.state = x, None => self.done = true } diff --git a/src/libcore/num/f32.rs b/src/libcore/num/f32.rs index 521085bca7638..ba03bb8f3d5c1 100644 --- a/src/libcore/num/f32.rs +++ b/src/libcore/num/f32.rs @@ -114,9 +114,15 @@ impl Float for f32 { #[inline] fn neg_infinity() -> f32 { NEG_INFINITY } + #[inline] + fn zero() -> f32 { 0.0 } + #[inline] fn neg_zero() -> f32 { -0.0 } + #[inline] + fn one() -> f32 { 1.0 } + /// Returns `true` if the number is NaN. #[inline] fn is_nan(self) -> bool { self != self } @@ -177,9 +183,15 @@ impl Float for f32 { #[inline] fn max_10_exp(_: Option) -> int { MAX_10_EXP } + #[inline] + fn min_value() -> f32 { MIN_VALUE } + #[inline] fn min_pos_value(_: Option) -> f32 { MIN_POS_VALUE } + #[inline] + fn max_value() -> f32 { MAX_VALUE } + /// Returns the mantissa, exponent and sign as integers. fn integer_decode(self) -> (u64, i16, i8) { let bits: u32 = unsafe { mem::transmute(self) }; @@ -222,12 +234,49 @@ impl Float for f32 { /// The fractional part of the number, satisfying: /// /// ```rust + /// use core::num::Float; + /// /// let x = 1.65f32; /// assert!(x == x.trunc() + x.fract()) /// ``` #[inline] fn fract(self) -> f32 { self - self.trunc() } + /// Computes the absolute value of `self`. Returns `Float::nan()` if the + /// number is `Float::nan()`. + #[inline] + fn abs(self) -> f32 { + unsafe { intrinsics::fabsf32(self) } + } + + /// Returns a number that represents the sign of `self`. + /// + /// - `1.0` if the number is positive, `+0.0` or `Float::infinity()` + /// - `-1.0` if the number is negative, `-0.0` or `Float::neg_infinity()` + /// - `Float::nan()` if the number is `Float::nan()` + #[inline] + fn signum(self) -> f32 { + if self.is_nan() { + Float::nan() + } else { + unsafe { intrinsics::copysignf32(1.0, self) } + } + } + + /// Returns `true` if `self` is positive, including `+0.0` and + /// `Float::infinity()`. + #[inline] + fn is_positive(self) -> bool { + self > 0.0 || (1.0 / self) == Float::infinity() + } + + /// Returns `true` if `self` is negative, including `-0.0` and + /// `Float::neg_infinity()`. + #[inline] + fn is_negative(self) -> bool { + self < 0.0 || (1.0 / self) == Float::neg_infinity() + } + /// Fused multiply-add. Computes `(self * a) + b` with only one rounding /// error. This produces a more accurate result with better performance than /// a separate multiplication operation followed by an add. @@ -240,6 +289,7 @@ impl Float for f32 { #[inline] fn recip(self) -> f32 { 1.0 / self } + #[inline] fn powi(self, n: i32) -> f32 { unsafe { intrinsics::powif32(self, n) } } diff --git a/src/libcore/num/f64.rs b/src/libcore/num/f64.rs index 78065d7803e0b..f1af4f0272c6b 100644 --- a/src/libcore/num/f64.rs +++ b/src/libcore/num/f64.rs @@ -120,9 +120,15 @@ impl Float for f64 { #[inline] fn neg_infinity() -> f64 { NEG_INFINITY } + #[inline] + fn zero() -> f64 { 0.0 } + #[inline] fn neg_zero() -> f64 { -0.0 } + #[inline] + fn one() -> f64 { 1.0 } + /// Returns `true` if the number is NaN. #[inline] fn is_nan(self) -> bool { self != self } @@ -183,9 +189,15 @@ impl Float for f64 { #[inline] fn max_10_exp(_: Option) -> int { MAX_10_EXP } + #[inline] + fn min_value() -> f64 { MIN_VALUE } + #[inline] fn min_pos_value(_: Option) -> f64 { MIN_POS_VALUE } + #[inline] + fn max_value() -> f64 { MAX_VALUE } + /// Returns the mantissa, exponent and sign as integers. fn integer_decode(self) -> (u64, i16, i8) { let bits: u64 = unsafe { mem::transmute(self) }; @@ -228,12 +240,49 @@ impl Float for f64 { /// The fractional part of the number, satisfying: /// /// ```rust + /// use core::num::Float; + /// /// let x = 1.65f64; /// assert!(x == x.trunc() + x.fract()) /// ``` #[inline] fn fract(self) -> f64 { self - self.trunc() } + /// Computes the absolute value of `self`. Returns `Float::nan()` if the + /// number is `Float::nan()`. + #[inline] + fn abs(self) -> f64 { + unsafe { intrinsics::fabsf64(self) } + } + + /// Returns a number that represents the sign of `self`. + /// + /// - `1.0` if the number is positive, `+0.0` or `Float::infinity()` + /// - `-1.0` if the number is negative, `-0.0` or `Float::neg_infinity()` + /// - `Float::nan()` if the number is `Float::nan()` + #[inline] + fn signum(self) -> f64 { + if self.is_nan() { + Float::nan() + } else { + unsafe { intrinsics::copysignf64(1.0, self) } + } + } + + /// Returns `true` if `self` is positive, including `+0.0` and + /// `Float::infinity()`. + #[inline] + fn is_positive(self) -> bool { + self > 0.0 || (1.0 / self) == Float::infinity() + } + + /// Returns `true` if `self` is negative, including `-0.0` and + /// `Float::neg_infinity()`. + #[inline] + fn is_negative(self) -> bool { + self < 0.0 || (1.0 / self) == Float::neg_infinity() + } + /// Fused multiply-add. Computes `(self * a) + b` with only one rounding /// error. This produces a more accurate result with better performance than /// a separate multiplication operation followed by an add. diff --git a/src/libcore/num/float_macros.rs b/src/libcore/num/float_macros.rs index 3e403219a4fba..d15cff3a8a9e3 100644 --- a/src/libcore/num/float_macros.rs +++ b/src/libcore/num/float_macros.rs @@ -13,6 +13,7 @@ macro_rules! assert_approx_eq( ($a:expr, $b:expr) => ({ + use num::Float; 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/mod.rs b/src/libcore/num/mod.rs index d14bcb3694449..216d140ac4897 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -10,7 +10,7 @@ // // ignore-lexer-test FIXME #15679 -//! Numeric traits and functions for generic mathematics +//! Numeric traits and functions for the built-in numeric types. #![allow(missing_docs)] @@ -19,298 +19,21 @@ use {int, i8, i16, i32, i64}; use {uint, u8, u16, u32, u64}; use {f32, f64}; use clone::Clone; -use cmp::{Ord, PartialEq, PartialOrd}; +use cmp::{PartialEq, Eq}; +use cmp::{PartialOrd, Ord}; use kinds::Copy; use mem::size_of; use ops::{Add, Sub, Mul, Div, Rem, Neg}; use ops::{Not, BitAnd, BitOr, BitXor, Shl, Shr}; use option::{Option, Some, None}; -/// The base trait for numeric types -pub trait Num: PartialEq + Zero + One - + Neg - + Add - + Sub - + Mul - + Div - + Rem {} - -macro_rules! trait_impl( - ($name:ident for $($t:ty)*) => ($( - impl $name for $t {} - )*) -) - -trait_impl!(Num for uint u8 u16 u32 u64 int i8 i16 i32 i64 f32 f64) - /// Simultaneous division and remainder #[inline] pub fn div_rem + Rem>(x: T, y: T) -> (T, T) { (x / y, x % y) } -/// Defines an additive identity element for `Self`. -/// -/// # Deriving -/// -/// This trait can be automatically be derived using `#[deriving(Zero)]` -/// attribute. If you choose to use this, make sure that the laws outlined in -/// the documentation for `Zero::zero` still hold. -pub trait Zero: Add { - /// Returns the additive identity element of `Self`, `0`. - /// - /// # Laws - /// - /// ```{.text} - /// a + 0 = a ∀ a ∈ Self - /// 0 + a = a ∀ a ∈ Self - /// ``` - /// - /// # Purity - /// - /// This function should return the same result at all times regardless of - /// external mutable state, for example values stored in TLS or in - /// `static mut`s. - // FIXME (#5527): This should be an associated constant - fn zero() -> Self; - - /// Returns `true` if `self` is equal to the additive identity. - #[inline] - fn is_zero(&self) -> bool; -} - -macro_rules! zero_impl( - ($t:ty, $v:expr) => { - impl Zero for $t { - #[inline] - fn zero() -> $t { $v } - #[inline] - fn is_zero(&self) -> bool { *self == $v } - } - } -) - -zero_impl!(uint, 0u) -zero_impl!(u8, 0u8) -zero_impl!(u16, 0u16) -zero_impl!(u32, 0u32) -zero_impl!(u64, 0u64) - -zero_impl!(int, 0i) -zero_impl!(i8, 0i8) -zero_impl!(i16, 0i16) -zero_impl!(i32, 0i32) -zero_impl!(i64, 0i64) - -zero_impl!(f32, 0.0f32) -zero_impl!(f64, 0.0f64) - -/// Returns the additive identity, `0`. -#[inline(always)] pub fn zero() -> T { Zero::zero() } - -/// Defines a multiplicative identity element for `Self`. -pub trait One: Mul { - /// Returns the multiplicative identity element of `Self`, `1`. - /// - /// # Laws - /// - /// ```{.text} - /// a * 1 = a ∀ a ∈ Self - /// 1 * a = a ∀ a ∈ Self - /// ``` - /// - /// # Purity - /// - /// This function should return the same result at all times regardless of - /// external mutable state, for example values stored in TLS or in - /// `static mut`s. - // FIXME (#5527): This should be an associated constant - fn one() -> Self; -} - -macro_rules! one_impl( - ($t:ty, $v:expr) => { - impl One for $t { - #[inline] - fn one() -> $t { $v } - } - } -) - -one_impl!(uint, 1u) -one_impl!(u8, 1u8) -one_impl!(u16, 1u16) -one_impl!(u32, 1u32) -one_impl!(u64, 1u64) - -one_impl!(int, 1i) -one_impl!(i8, 1i8) -one_impl!(i16, 1i16) -one_impl!(i32, 1i32) -one_impl!(i64, 1i64) - -one_impl!(f32, 1.0f32) -one_impl!(f64, 1.0f64) - -/// Returns the multiplicative identity, `1`. -#[inline(always)] pub fn one() -> T { One::one() } - -/// Useful functions for signed numbers (i.e. numbers that can be negative). -pub trait Signed: Num + Neg { - /// Computes the absolute value. - /// - /// For `f32` and `f64`, `NaN` will be returned if the number is `NaN`. - /// - /// For signed integers, `::MIN` will be returned if the number is `::MIN`. - fn abs(&self) -> Self; - - /// The positive difference of two numbers. - /// - /// Returns `zero` if the number is less than or equal to `other`, otherwise the difference - /// between `self` and `other` is returned. - fn abs_sub(&self, other: &Self) -> Self; - - /// Returns the sign of the number. - /// - /// For `f32` and `f64`: - /// - /// * `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` - /// - /// For signed integers: - /// - /// * `0` if the number is zero - /// * `1` if the number is positive - /// * `-1` if the number is negative - fn signum(&self) -> Self; - - /// Returns true if the number is positive and false if the number is zero or negative. - fn is_positive(&self) -> bool; - - /// Returns true if the number is negative and false if the number is zero or positive. - fn is_negative(&self) -> bool; -} - -macro_rules! signed_impl( - ($($t:ty)*) => ($( - impl Signed for $t { - #[inline] - fn abs(&self) -> $t { - if self.is_negative() { -*self } else { *self } - } - - #[inline] - fn abs_sub(&self, other: &$t) -> $t { - if *self <= *other { 0 } else { *self - *other } - } - - #[inline] - fn signum(&self) -> $t { - match *self { - n if n > 0 => 1, - 0 => 0, - _ => -1, - } - } - - #[inline] - fn is_positive(&self) -> bool { *self > 0 } - - #[inline] - fn is_negative(&self) -> bool { *self < 0 } - } - )*) -) - -signed_impl!(int i8 i16 i32 i64) - -macro_rules! signed_float_impl( - ($t:ty, $nan:expr, $inf:expr, $neg_inf:expr, $fabs:path, $fcopysign:path, $fdim:ident) => { - impl Signed for $t { - /// Computes the absolute value. Returns `NAN` if the number is `NAN`. - #[inline] - fn abs(&self) -> $t { - unsafe { $fabs(*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: &$t) -> $t { - extern { fn $fdim(a: $t, b: $t) -> $t; } - 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) -> $t { - if self != self { $nan } else { - unsafe { $fcopysign(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) == $inf } - - /// 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_inf } - } - } -) - -signed_float_impl!(f32, f32::NAN, f32::INFINITY, f32::NEG_INFINITY, - intrinsics::fabsf32, intrinsics::copysignf32, fdimf) -signed_float_impl!(f64, f64::NAN, f64::INFINITY, f64::NEG_INFINITY, - intrinsics::fabsf64, intrinsics::copysignf64, fdim) - -/// Computes the absolute value. -/// -/// For `f32` and `f64`, `NaN` will be returned if the number is `NaN` -/// -/// For signed integers, `::MIN` will be returned if the number is `::MIN`. -#[inline(always)] -pub fn abs(value: T) -> T { - value.abs() -} - -/// The positive difference of two numbers. -/// -/// Returns zero if `x` is less than or equal to `y`, otherwise the difference -/// between `x` and `y` is returned. -#[inline(always)] -pub fn abs_sub(x: T, y: T) -> T { - x.abs_sub(&y) -} - -/// Returns the sign of the number. -/// -/// For `f32` and `f64`: -/// -/// * `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` -/// -/// For signed integers: -/// -/// * `0` if the number is zero -/// * `1` if the number is positive -/// * `-1` if the number is negative -#[inline(always)] pub fn signum(value: T) -> T { value.signum() } - -/// A trait for values which cannot be negative -pub trait Unsigned: Num {} - -trait_impl!(Unsigned for uint u8 u16 u32 u64) - -/// Raises a value to the power of exp, using exponentiation by squaring. +/// Raises a `base` to the power of `exp`, using exponentiation by squaring. /// /// # Example /// @@ -320,10 +43,10 @@ trait_impl!(Unsigned for uint u8 u16 u32 u64) /// assert_eq!(num::pow(2i, 4), 16); /// ``` #[inline] -pub fn pow>(mut base: T, mut exp: uint) -> T { +pub fn pow(mut base: T, mut exp: uint) -> T { if exp == 1 { base } else { - let mut acc = one::(); + let mut acc: T = Int::one(); while exp > 0 { if (exp & 1) == 1 { acc = acc * base; @@ -335,85 +58,60 @@ pub fn pow>(mut base: T, mut exp: uint) -> T { } } -/// Numbers which have upper and lower bounds -pub trait Bounded { - // FIXME (#5527): These should be associated constants - /// returns the smallest finite number this type can represent - fn min_value() -> Self; - /// returns the largest finite number this type can represent - fn max_value() -> Self; -} - -macro_rules! bounded_impl( - ($t:ty, $min:expr, $max:expr) => { - impl Bounded for $t { - #[inline] - fn min_value() -> $t { $min } - - #[inline] - fn max_value() -> $t { $max } - } - } -) - -bounded_impl!(uint, uint::MIN, uint::MAX) -bounded_impl!(u8, u8::MIN, u8::MAX) -bounded_impl!(u16, u16::MIN, u16::MAX) -bounded_impl!(u32, u32::MIN, u32::MAX) -bounded_impl!(u64, u64::MIN, u64::MAX) - -bounded_impl!(int, int::MIN, int::MAX) -bounded_impl!(i8, i8::MIN, i8::MAX) -bounded_impl!(i16, i16::MIN, i16::MAX) -bounded_impl!(i32, i32::MIN, i32::MAX) -bounded_impl!(i64, i64::MIN, i64::MAX) +/// A built-in signed or unsigned integer. +pub trait Int + : Copy + Clone + + NumCast + + PartialOrd + Ord + + PartialEq + Eq + + Add + + Sub + + Mul + + Div + + Rem + + Not + + BitAnd + + BitOr + + BitXor + + Shl + + Shr +{ + /// Returns the `0` value of this integer type. + // FIXME (#5527): Should be an associated constant + fn zero() -> Self; -bounded_impl!(f32, f32::MIN_VALUE, f32::MAX_VALUE) -bounded_impl!(f64, f64::MIN_VALUE, f64::MAX_VALUE) + /// Returns the `1` value of this integer type. + // FIXME (#5527): Should be an associated constant + fn one() -> Self; -/// Specifies the available operations common to all of Rust's core numeric primitives. -/// These may not always make sense from a purely mathematical point of view, but -/// may be useful for systems programming. -pub trait Primitive: Copy - + Clone - + Num - + NumCast - + PartialOrd - + Bounded {} + /// Returns the smallest value that can be represented by this integer type. + // FIXME (#5527): Should be and associated constant + fn min_value() -> Self; -trait_impl!(Primitive for uint u8 u16 u32 u64 int i8 i16 i32 i64 f32 f64) + /// Returns the largest value that can be represented by this integer type. + // FIXME (#5527): Should be and associated constant + fn max_value() -> Self; -/// A primitive signed or unsigned integer equipped with various bitwise -/// operators, bit counting methods, and endian conversion functions. -pub trait Int: Primitive - + Ord - + CheckedAdd - + CheckedSub - + CheckedMul - + CheckedDiv - + Bounded - + Not - + BitAnd - + BitOr - + BitXor - + Shl - + Shr { - /// Returns the number of ones in the binary representation of the integer. + /// Returns the number of ones in the binary representation of `self`. /// /// # Example /// /// ```rust + /// use std::num::Int; + /// /// let n = 0b01001100u8; /// /// assert_eq!(n.count_ones(), 3); /// ``` fn count_ones(self) -> uint; - /// Returns the number of zeros in the binary representation of the integer. + /// Returns the number of zeros in the binary representation of `self`. /// /// # Example /// /// ```rust + /// use std::num::Int; + /// /// let n = 0b01001100u8; /// /// assert_eq!(n.count_zeros(), 5); @@ -424,11 +122,13 @@ pub trait Int: Primitive } /// Returns the number of leading zeros in the binary representation - /// of the integer. + /// of `self`. /// /// # Example /// /// ```rust + /// use std::num::Int; + /// /// let n = 0b0101000u16; /// /// assert_eq!(n.leading_zeros(), 10); @@ -436,11 +136,13 @@ pub trait Int: Primitive fn leading_zeros(self) -> uint; /// Returns the number of trailing zeros in the binary representation - /// of the integer. + /// of `self`. /// /// # Example /// /// ```rust + /// use std::num::Int; + /// /// let n = 0b0101000u16; /// /// assert_eq!(n.trailing_zeros(), 3); @@ -453,6 +155,8 @@ pub trait Int: Primitive /// # Example /// /// ```rust + /// use std::num::Int; + /// /// let n = 0x0123456789ABCDEFu64; /// let m = 0x3456789ABCDEF012u64; /// @@ -466,6 +170,8 @@ pub trait Int: Primitive /// # Example /// /// ```rust + /// use std::num::Int; + /// /// let n = 0x0123456789ABCDEFu64; /// let m = 0xDEF0123456789ABCu64; /// @@ -478,6 +184,8 @@ pub trait Int: Primitive /// # Example /// /// ```rust + /// use std::num::Int; + /// /// let n = 0x0123456789ABCDEFu64; /// let m = 0xEFCDAB8967452301u64; /// @@ -492,6 +200,8 @@ pub trait Int: Primitive /// # Example /// /// ```rust + /// use std::num::Int; + /// /// let n = 0x0123456789ABCDEFu64; /// /// if cfg!(target_endian = "big") { @@ -512,6 +222,8 @@ pub trait Int: Primitive /// # Example /// /// ```rust + /// use std::num::Int; + /// /// let n = 0x0123456789ABCDEFu64; /// /// if cfg!(target_endian = "little") { @@ -525,13 +237,15 @@ pub trait Int: Primitive if cfg!(target_endian = "little") { x } else { x.swap_bytes() } } - /// Convert the integer to big endian from the target's endianness. + /// Convert `self` to big endian from the target's endianness. /// /// On big endian this is a no-op. On little endian the bytes are swapped. /// /// # Example /// /// ```rust + /// use std::num::Int; + /// /// let n = 0x0123456789ABCDEFu64; /// /// if cfg!(target_endian = "big") { @@ -545,13 +259,15 @@ pub trait Int: Primitive if cfg!(target_endian = "big") { self } else { self.swap_bytes() } } - /// Convert the integer to little endian from the target's endianness. + /// Convert `self` to little endian from the target's endianness. /// /// On little endian this is a no-op. On big endian the bytes are swapped. /// /// # Example /// /// ```rust + /// use std::num::Int; + /// /// let n = 0x0123456789ABCDEFu64; /// /// if cfg!(target_endian = "little") { @@ -564,19 +280,121 @@ pub trait Int: Primitive fn to_le(self) -> Self { if cfg!(target_endian = "little") { self } else { self.swap_bytes() } } + + /// Checked integer addition. Computes `self + other`, returning `None` if + /// overflow occurred. + /// + /// # Example + /// + /// ```rust + /// use std::num::Int; + /// + /// assert_eq!(5u16.checked_add(65530), Some(65535)); + /// assert_eq!(6u16.checked_add(65530), None); + /// ``` + fn checked_add(self, other: Self) -> Option; + + /// Checked integer subtraction. Computes `self + other`, returning `None` + /// if underflow occurred. + /// + /// # Example + /// + /// ```rust + /// use std::num::Int; + /// + /// assert_eq!((-127i8).checked_sub(1), Some(-128)); + /// assert_eq!((-128i8).checked_sub(1), None); + /// ``` + fn checked_sub(self, other: Self) -> Option; + + /// Checked integer multiplication. Computes `self + other`, returning + /// `None` if underflow or overflow occurred. + /// + /// # Example + /// + /// ```rust + /// use std::num::Int; + /// + /// assert_eq!(5u8.checked_mul(51), Some(255)); + /// assert_eq!(5u8.checked_mul(52), None); + /// ``` + fn checked_mul(self, other: Self) -> Option; + + /// Checked integer division. Computes `self + other` returning `None` if + /// `self == 0` or the operation results in underflow or overflow. + /// + /// # Example + /// + /// ```rust + /// use std::num::Int; + /// + /// assert_eq!((-127i8).checked_div(-1), Some(127)); + /// assert_eq!((-128i8).checked_div(-1), None); + /// assert_eq!((1i8).checked_div(0), None); + /// ``` + #[inline] + fn checked_div(self, other: Self) -> Option; + + /// Saturating integer addition. Computes `self + other`, saturating at + /// the numeric bounds instead of overflowing. + #[inline] + fn saturating_add(self, other: Self) -> Self { + match self.checked_add(other) { + Some(x) => x, + None if other >= Int::zero() => Int::max_value(), + None => Int::min_value(), + } + } + + /// Saturating integer subtraction. Computes `self - other`, saturating at + /// the numeric bounds instead of overflowing. + #[inline] + fn saturating_sub(self, other: Self) -> Self { + match self.checked_sub(other) { + Some(x) => x, + None if other >= Int::zero() => Int::min_value(), + None => Int::max_value(), + } + } } -macro_rules! int_impl { - ($T:ty, $BITS:expr, $ctpop:path, $ctlz:path, $cttz:path, $bswap:path) => { +macro_rules! checked_op { + ($T:ty, $U:ty, $op:path, $x:expr, $y:expr) => {{ + let (result, overflowed) = unsafe { $op($x as $U, $y as $U) }; + if overflowed { None } else { Some(result as $T) } + }} +} + +macro_rules! uint_impl { + ($T:ty = $ActualT:ty, $BITS:expr, + $ctpop:path, + $ctlz:path, + $cttz:path, + $bswap:path, + $add_with_overflow:path, + $sub_with_overflow:path, + $mul_with_overflow:path) => { impl Int for $T { #[inline] - fn count_ones(self) -> uint { unsafe { $ctpop(self) as uint } } + fn zero() -> $T { 0 } + + #[inline] + fn one() -> $T { 1 } + + #[inline] + fn min_value() -> $T { 0 } + + #[inline] + fn max_value() -> $T { -1 } + + #[inline] + fn count_ones(self) -> uint { unsafe { $ctpop(self as $ActualT) as uint } } #[inline] - fn leading_zeros(self) -> uint { unsafe { $ctlz(self) as uint } } + fn leading_zeros(self) -> uint { unsafe { $ctlz(self as $ActualT) as uint } } #[inline] - fn trailing_zeros(self) -> uint { unsafe { $cttz(self) as uint } } + fn trailing_zeros(self) -> uint { unsafe { $cttz(self as $ActualT) as uint } } #[inline] fn rotate_left(self, n: uint) -> $T { @@ -593,7 +411,30 @@ macro_rules! int_impl { } #[inline] - fn swap_bytes(self) -> $T { unsafe { $bswap(self) } } + fn swap_bytes(self) -> $T { unsafe { $bswap(self as $ActualT) as $T } } + + #[inline] + fn checked_add(self, other: $T) -> Option<$T> { + checked_op!($T, $ActualT, $add_with_overflow, self, other) + } + + #[inline] + fn checked_sub(self, other: $T) -> Option<$T> { + checked_op!($T, $ActualT, $sub_with_overflow, self, other) + } + + #[inline] + fn checked_mul(self, other: $T) -> Option<$T> { + checked_op!($T, $ActualT, $mul_with_overflow, self, other) + } + + #[inline] + fn checked_div(self, v: $T) -> Option<$T> { + match v { + 0 => None, + v => Some(self / v), + } + } } } } @@ -602,98 +443,256 @@ macro_rules! int_impl { /// consistency with the other `bswap` intrinsics. unsafe fn bswap8(x: u8) -> u8 { x } -int_impl!(u8, 8, +uint_impl!(u8 = u8, 8, intrinsics::ctpop8, intrinsics::ctlz8, intrinsics::cttz8, - bswap8) + bswap8, + intrinsics::u8_add_with_overflow, + intrinsics::u8_sub_with_overflow, + intrinsics::u8_mul_with_overflow) -int_impl!(u16, 16, +uint_impl!(u16 = u16, 16, intrinsics::ctpop16, intrinsics::ctlz16, intrinsics::cttz16, - intrinsics::bswap16) + intrinsics::bswap16, + intrinsics::u16_add_with_overflow, + intrinsics::u16_sub_with_overflow, + intrinsics::u16_mul_with_overflow) + +uint_impl!(u32 = u32, 32, + intrinsics::ctpop32, + intrinsics::ctlz32, + intrinsics::cttz32, + intrinsics::bswap32, + intrinsics::u32_add_with_overflow, + intrinsics::u32_sub_with_overflow, + intrinsics::u32_mul_with_overflow) + +uint_impl!(u64 = u64, 64, + intrinsics::ctpop64, + intrinsics::ctlz64, + intrinsics::cttz64, + intrinsics::bswap64, + intrinsics::u64_add_with_overflow, + intrinsics::u64_sub_with_overflow, + intrinsics::u64_mul_with_overflow) -int_impl!(u32, 32, +#[cfg(target_word_size = "32")] +uint_impl!(uint = u32, 32, intrinsics::ctpop32, intrinsics::ctlz32, intrinsics::cttz32, - intrinsics::bswap32) + intrinsics::bswap32, + intrinsics::u32_add_with_overflow, + intrinsics::u32_sub_with_overflow, + intrinsics::u32_mul_with_overflow) -int_impl!(u64, 64, +#[cfg(target_word_size = "64")] +uint_impl!(uint = u64, 64, intrinsics::ctpop64, intrinsics::ctlz64, intrinsics::cttz64, - intrinsics::bswap64) + intrinsics::bswap64, + intrinsics::u64_add_with_overflow, + intrinsics::u64_sub_with_overflow, + intrinsics::u64_mul_with_overflow) -macro_rules! int_cast_impl { - ($T:ty, $U:ty) => { +macro_rules! int_impl { + ($T:ty = $ActualT:ty, $UnsignedT:ty, $BITS:expr, + $add_with_overflow:path, + $sub_with_overflow:path, + $mul_with_overflow:path) => { impl Int for $T { #[inline] - fn count_ones(self) -> uint { (self as $U).count_ones() } + fn zero() -> $T { 0 } + + #[inline] + fn one() -> $T { 1 } + + #[inline] + fn min_value() -> $T { (-1 as $T) << ($BITS - 1) } + + #[inline] + fn max_value() -> $T { let min: $T = Int::min_value(); !min } + + #[inline] + fn count_ones(self) -> uint { (self as $UnsignedT).count_ones() } + + #[inline] + fn leading_zeros(self) -> uint { (self as $UnsignedT).leading_zeros() } + + #[inline] + fn trailing_zeros(self) -> uint { (self as $UnsignedT).trailing_zeros() } + + #[inline] + fn rotate_left(self, n: uint) -> $T { (self as $UnsignedT).rotate_left(n) as $T } + + #[inline] + fn rotate_right(self, n: uint) -> $T { (self as $UnsignedT).rotate_right(n) as $T } #[inline] - fn leading_zeros(self) -> uint { (self as $U).leading_zeros() } + fn swap_bytes(self) -> $T { (self as $UnsignedT).swap_bytes() as $T } #[inline] - fn trailing_zeros(self) -> uint { (self as $U).trailing_zeros() } + fn checked_add(self, other: $T) -> Option<$T> { + checked_op!($T, $ActualT, $add_with_overflow, self, other) + } #[inline] - fn rotate_left(self, n: uint) -> $T { (self as $U).rotate_left(n) as $T } + fn checked_sub(self, other: $T) -> Option<$T> { + checked_op!($T, $ActualT, $sub_with_overflow, self, other) + } #[inline] - fn rotate_right(self, n: uint) -> $T { (self as $U).rotate_right(n) as $T } + fn checked_mul(self, other: $T) -> Option<$T> { + checked_op!($T, $ActualT, $mul_with_overflow, self, other) + } #[inline] - fn swap_bytes(self) -> $T { (self as $U).swap_bytes() as $T } + fn checked_div(self, v: $T) -> Option<$T> { + match v { + 0 => None, + -1 if self == Int::min_value() + => None, + v => Some(self / v), + } + } } } } -int_cast_impl!(i8, u8) -int_cast_impl!(i16, u16) -int_cast_impl!(i32, u32) -int_cast_impl!(i64, u64) +int_impl!(i8 = i8, u8, 8, + intrinsics::i8_add_with_overflow, + intrinsics::i8_sub_with_overflow, + intrinsics::i8_mul_with_overflow) -#[cfg(target_word_size = "32")] int_cast_impl!(uint, u32) -#[cfg(target_word_size = "64")] int_cast_impl!(uint, u64) -#[cfg(target_word_size = "32")] int_cast_impl!(int, u32) -#[cfg(target_word_size = "64")] int_cast_impl!(int, u64) +int_impl!(i16 = i16, u16, 16, + intrinsics::i16_add_with_overflow, + intrinsics::i16_sub_with_overflow, + intrinsics::i16_mul_with_overflow) -/// Returns the smallest power of 2 greater than or equal to `n`. -#[inline] -pub fn next_power_of_two(n: T) -> T { - let halfbits = size_of::() * 4; - let mut tmp: T = n - one(); - let mut shift = 1u; - while shift <= halfbits { - tmp = tmp | (tmp >> shift); - shift = shift << 1u; - } - tmp + one() +int_impl!(i32 = i32, u32, 32, + intrinsics::i32_add_with_overflow, + intrinsics::i32_sub_with_overflow, + intrinsics::i32_mul_with_overflow) + +int_impl!(i64 = i64, u64, 64, + intrinsics::i64_add_with_overflow, + intrinsics::i64_sub_with_overflow, + intrinsics::i64_mul_with_overflow) + +#[cfg(target_word_size = "32")] +int_impl!(int = i32, u32, 32, + intrinsics::i32_add_with_overflow, + intrinsics::i32_sub_with_overflow, + intrinsics::i32_mul_with_overflow) + +#[cfg(target_word_size = "64")] +int_impl!(int = i64, u64, 64, + intrinsics::i64_add_with_overflow, + intrinsics::i64_sub_with_overflow, + intrinsics::i64_mul_with_overflow) + +/// A built-in two's complement integer. +pub trait SignedInt + : Int + + Neg +{ + /// Computes the absolute value of `self`. `Int::min_value()` will be + /// returned if the number is `Int::min_value()`. + fn abs(self) -> Self; + + /// Returns a number representing sign of `self`. + /// + /// - `0` if the number is zero + /// - `1` if the number is positive + /// - `-1` if the number is negative + fn signum(self) -> Self; + + /// Returns `true` if `self` is positive and `false` if the number + /// is zero or negative. + fn is_positive(self) -> bool; + + /// Returns `true` if `self` is negative and `false` if the number + /// is zero or positive. + fn is_negative(self) -> bool; } -// Returns `true` iff `n == 2^k` for some k. -#[inline] -pub fn is_power_of_two(n: T) -> bool { - (n - one()) & n == zero() +macro_rules! signed_int_impl { + ($T:ty) => { + impl SignedInt for $T { + #[inline] + fn abs(self) -> $T { + if self.is_negative() { -self } else { self } + } + + #[inline] + fn signum(self) -> $T { + match self { + n if n > 0 => 1, + 0 => 0, + _ => -1, + } + } + + #[inline] + fn is_positive(self) -> bool { self > 0 } + + #[inline] + fn is_negative(self) -> bool { self < 0 } + } + } } -/// Returns the smallest power of 2 greater than or equal to `n`. If the next -/// power of two is greater than the type's maximum value, `None` is returned, -/// otherwise the power of 2 is wrapped in `Some`. -#[inline] -pub fn checked_next_power_of_two(n: T) -> Option { - let halfbits = size_of::() * 4; - let mut tmp: T = n - one(); - let mut shift = 1u; - while shift <= halfbits { - tmp = tmp | (tmp >> shift); - shift = shift << 1u; +signed_int_impl!(i8) +signed_int_impl!(i16) +signed_int_impl!(i32) +signed_int_impl!(i64) +signed_int_impl!(int) + +/// A built-in unsigned integer. +pub trait UnsignedInt: Int { + /// Returns `true` iff `self == 2^k` for some `k`. + fn is_power_of_two(self) -> bool { + (self - Int::one()) & self == Int::zero() + } + + /// Returns the smallest power of two greater than or equal to `self`. + #[inline] + fn next_power_of_two(self) -> Self { + let halfbits = size_of::() * 4; + let mut tmp = self - Int::one(); + let mut shift = 1u; + while shift <= halfbits { + tmp = tmp | (tmp >> shift); + shift = shift << 1u; + } + tmp + Int::one() + } + + /// Returns the smallest power of two greater than or equal to `n`. If the + /// next power of two is greater than the type's maximum value, `None` is + /// returned, otherwise the power of two is wrapped in `Some`. + fn checked_next_power_of_two(self) -> Option { + let halfbits = size_of::() * 4; + let mut tmp = self - Int::one(); + let mut shift = 1u; + while shift <= halfbits { + tmp = tmp | (tmp >> shift); + shift = shift << 1u; + } + tmp.checked_add(Int::one()) } - tmp.checked_add(&one()) } +impl UnsignedInt for uint {} +impl UnsignedInt for u8 {} +impl UnsignedInt for u16 {} +impl UnsignedInt for u32 {} +impl UnsignedInt for u64 {} + /// A generic trait for converting a value to a number. pub trait ToPrimitive { /// Converts the value of `self` to an `int`. @@ -771,8 +770,8 @@ macro_rules! impl_to_primitive_int_to_int( Some($slf as $DstT) } else { let n = $slf as i64; - let min_value: $DstT = Bounded::min_value(); - let max_value: $DstT = Bounded::max_value(); + let min_value: $DstT = Int::min_value(); + let max_value: $DstT = Int::max_value(); if min_value as i64 <= n && n <= max_value as i64 { Some($slf as $DstT) } else { @@ -786,8 +785,8 @@ macro_rules! impl_to_primitive_int_to_int( macro_rules! impl_to_primitive_int_to_uint( ($SrcT:ty, $DstT:ty, $slf:expr) => ( { - let zero: $SrcT = Zero::zero(); - let max_value: $DstT = Bounded::max_value(); + let zero: $SrcT = Int::zero(); + let max_value: $DstT = Int::max_value(); if zero <= $slf && $slf as u64 <= max_value as u64 { Some($slf as $DstT) } else { @@ -839,7 +838,7 @@ impl_to_primitive_int!(i64) macro_rules! impl_to_primitive_uint_to_int( ($DstT:ty, $slf:expr) => ( { - let max_value: $DstT = Bounded::max_value(); + let max_value: $DstT = Int::max_value(); if $slf as u64 <= max_value as u64 { Some($slf as $DstT) } else { @@ -855,8 +854,8 @@ macro_rules! impl_to_primitive_uint_to_uint( if size_of::<$SrcT>() <= size_of::<$DstT>() { Some($slf as $DstT) } else { - let zero: $SrcT = Zero::zero(); - let max_value: $DstT = Bounded::max_value(); + let zero: $SrcT = Int::zero(); + let max_value: $DstT = Int::max_value(); if zero <= $slf && $slf as u64 <= max_value as u64 { Some($slf as $DstT) } else { @@ -912,7 +911,7 @@ macro_rules! impl_to_primitive_float_to_float( Some($slf as $DstT) } else { let n = $slf as f64; - let max_value: $SrcT = Bounded::max_value(); + let max_value: $SrcT = Float::max_value(); if -max_value as f64 <= n && n <= max_value as f64 { Some($slf as $DstT) } else { @@ -1182,229 +1181,6 @@ impl_num_cast!(int, to_int) impl_num_cast!(f32, to_f32) impl_num_cast!(f64, to_f64) -/// Saturating math operations -pub trait Saturating { - /// Saturating addition operator. - /// Returns a+b, saturating at the numeric bounds instead of overflowing. - fn saturating_add(self, v: Self) -> Self; - - /// Saturating subtraction operator. - /// Returns a-b, saturating at the numeric bounds instead of overflowing. - fn saturating_sub(self, v: Self) -> Self; -} - -impl Saturating for T { - #[inline] - fn saturating_add(self, v: T) -> T { - match self.checked_add(&v) { - Some(x) => x, - None => if v >= Zero::zero() { - Bounded::max_value() - } else { - Bounded::min_value() - } - } - } - - #[inline] - fn saturating_sub(self, v: T) -> T { - match self.checked_sub(&v) { - Some(x) => x, - None => if v >= Zero::zero() { - Bounded::min_value() - } else { - Bounded::max_value() - } - } - } -} - -/// Performs addition that returns `None` instead of wrapping around on overflow. -pub trait CheckedAdd: Add { - /// Adds two numbers, checking for overflow. If overflow happens, `None` is returned. - /// - /// # Example - /// - /// ```rust - /// use std::num::CheckedAdd; - /// assert_eq!(5u16.checked_add(&65530), Some(65535)); - /// assert_eq!(6u16.checked_add(&65530), None); - /// ``` - fn checked_add(&self, v: &Self) -> Option; -} - -macro_rules! checked_impl( - ($trait_name:ident, $method:ident, $t:ty, $op:path) => { - impl $trait_name for $t { - #[inline] - fn $method(&self, v: &$t) -> Option<$t> { - unsafe { - let (x, y) = $op(*self, *v); - if y { None } else { Some(x) } - } - } - } - } -) -macro_rules! checked_cast_impl( - ($trait_name:ident, $method:ident, $t:ty, $cast:ty, $op:path) => { - impl $trait_name for $t { - #[inline] - fn $method(&self, v: &$t) -> Option<$t> { - unsafe { - let (x, y) = $op(*self as $cast, *v as $cast); - if y { None } else { Some(x as $t) } - } - } - } - } -) - -#[cfg(target_word_size = "32")] -checked_cast_impl!(CheckedAdd, checked_add, uint, u32, intrinsics::u32_add_with_overflow) -#[cfg(target_word_size = "64")] -checked_cast_impl!(CheckedAdd, checked_add, uint, u64, intrinsics::u64_add_with_overflow) - -checked_impl!(CheckedAdd, checked_add, u8, intrinsics::u8_add_with_overflow) -checked_impl!(CheckedAdd, checked_add, u16, intrinsics::u16_add_with_overflow) -checked_impl!(CheckedAdd, checked_add, u32, intrinsics::u32_add_with_overflow) -checked_impl!(CheckedAdd, checked_add, u64, intrinsics::u64_add_with_overflow) - -#[cfg(target_word_size = "32")] -checked_cast_impl!(CheckedAdd, checked_add, int, i32, intrinsics::i32_add_with_overflow) -#[cfg(target_word_size = "64")] -checked_cast_impl!(CheckedAdd, checked_add, int, i64, intrinsics::i64_add_with_overflow) - -checked_impl!(CheckedAdd, checked_add, i8, intrinsics::i8_add_with_overflow) -checked_impl!(CheckedAdd, checked_add, i16, intrinsics::i16_add_with_overflow) -checked_impl!(CheckedAdd, checked_add, i32, intrinsics::i32_add_with_overflow) -checked_impl!(CheckedAdd, checked_add, i64, intrinsics::i64_add_with_overflow) - -/// Performs subtraction that returns `None` instead of wrapping around on underflow. -pub trait CheckedSub: Sub { - /// Subtracts two numbers, checking for underflow. If underflow happens, `None` is returned. - /// - /// # Example - /// - /// ```rust - /// use std::num::CheckedSub; - /// assert_eq!((-127i8).checked_sub(&1), Some(-128)); - /// assert_eq!((-128i8).checked_sub(&1), None); - /// ``` - fn checked_sub(&self, v: &Self) -> Option; -} - -#[cfg(target_word_size = "32")] -checked_cast_impl!(CheckedSub, checked_sub, uint, u32, intrinsics::u32_sub_with_overflow) -#[cfg(target_word_size = "64")] -checked_cast_impl!(CheckedSub, checked_sub, uint, u64, intrinsics::u64_sub_with_overflow) - -checked_impl!(CheckedSub, checked_sub, u8, intrinsics::u8_sub_with_overflow) -checked_impl!(CheckedSub, checked_sub, u16, intrinsics::u16_sub_with_overflow) -checked_impl!(CheckedSub, checked_sub, u32, intrinsics::u32_sub_with_overflow) -checked_impl!(CheckedSub, checked_sub, u64, intrinsics::u64_sub_with_overflow) - -#[cfg(target_word_size = "32")] -checked_cast_impl!(CheckedSub, checked_sub, int, i32, intrinsics::i32_sub_with_overflow) -#[cfg(target_word_size = "64")] -checked_cast_impl!(CheckedSub, checked_sub, int, i64, intrinsics::i64_sub_with_overflow) - -checked_impl!(CheckedSub, checked_sub, i8, intrinsics::i8_sub_with_overflow) -checked_impl!(CheckedSub, checked_sub, i16, intrinsics::i16_sub_with_overflow) -checked_impl!(CheckedSub, checked_sub, i32, intrinsics::i32_sub_with_overflow) -checked_impl!(CheckedSub, checked_sub, i64, intrinsics::i64_sub_with_overflow) - -/// Performs multiplication that returns `None` instead of wrapping around on underflow or -/// overflow. -pub trait CheckedMul: Mul { - /// Multiplies two numbers, checking for underflow or overflow. If underflow or overflow - /// happens, `None` is returned. - /// - /// # Example - /// - /// ```rust - /// use std::num::CheckedMul; - /// assert_eq!(5u8.checked_mul(&51), Some(255)); - /// assert_eq!(5u8.checked_mul(&52), None); - /// ``` - fn checked_mul(&self, v: &Self) -> Option; -} - -#[cfg(target_word_size = "32")] -checked_cast_impl!(CheckedMul, checked_mul, uint, u32, intrinsics::u32_mul_with_overflow) -#[cfg(target_word_size = "64")] -checked_cast_impl!(CheckedMul, checked_mul, uint, u64, intrinsics::u64_mul_with_overflow) - -checked_impl!(CheckedMul, checked_mul, u8, intrinsics::u8_mul_with_overflow) -checked_impl!(CheckedMul, checked_mul, u16, intrinsics::u16_mul_with_overflow) -checked_impl!(CheckedMul, checked_mul, u32, intrinsics::u32_mul_with_overflow) -checked_impl!(CheckedMul, checked_mul, u64, intrinsics::u64_mul_with_overflow) - -#[cfg(target_word_size = "32")] -checked_cast_impl!(CheckedMul, checked_mul, int, i32, intrinsics::i32_mul_with_overflow) -#[cfg(target_word_size = "64")] -checked_cast_impl!(CheckedMul, checked_mul, int, i64, intrinsics::i64_mul_with_overflow) - -checked_impl!(CheckedMul, checked_mul, i8, intrinsics::i8_mul_with_overflow) -checked_impl!(CheckedMul, checked_mul, i16, intrinsics::i16_mul_with_overflow) -checked_impl!(CheckedMul, checked_mul, i32, intrinsics::i32_mul_with_overflow) -checked_impl!(CheckedMul, checked_mul, i64, intrinsics::i64_mul_with_overflow) - -/// Performs division that returns `None` instead of panicking on division by zero and instead of -/// wrapping around on underflow and overflow. -pub trait CheckedDiv: Div { - /// Divides two numbers, checking for underflow, overflow and division by zero. If any of that - /// happens, `None` is returned. - /// - /// # Example - /// - /// ```rust - /// use std::num::CheckedDiv; - /// assert_eq!((-127i8).checked_div(&-1), Some(127)); - /// assert_eq!((-128i8).checked_div(&-1), None); - /// assert_eq!((1i8).checked_div(&0), None); - /// ``` - fn checked_div(&self, v: &Self) -> Option; -} - -macro_rules! checkeddiv_int_impl( - ($t:ty, $min:expr) => { - 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) - } - } - } - } -) - -checkeddiv_int_impl!(int, int::MIN) -checkeddiv_int_impl!(i8, i8::MIN) -checkeddiv_int_impl!(i16, i16::MIN) -checkeddiv_int_impl!(i32, i32::MIN) -checkeddiv_int_impl!(i64, i64::MIN) - -macro_rules! checkeddiv_uint_impl( - ($($t:ty)*) => ($( - impl CheckedDiv for $t { - #[inline] - fn checked_div(&self, v: &$t) -> Option<$t> { - if *v == 0 { - None - } else { - Some(*self / *v) - } - } - } - )*) -) - -checkeddiv_uint_impl!(uint u8 u16 u32 u64) - /// Used for representing the classification of floating point numbers #[deriving(PartialEq, Show)] pub enum FPCategory { @@ -1420,21 +1196,36 @@ pub enum FPCategory { FPNormal, } -/// Operations on primitive floating point numbers. +/// A built-in floating point number. // FIXME(#5527): In a future version of Rust, many of these functions will // become constants. // // FIXME(#8888): Several of these functions have a parameter named // `unused_self`. Removing it requires #8888 to be fixed. -pub trait Float: Signed + Primitive { +pub trait Float + : Copy + Clone + + NumCast + + PartialOrd + + PartialEq + + Neg + + Add + + Sub + + Mul + + Div + + Rem +{ /// Returns the NaN value. fn nan() -> Self; /// Returns the infinite value. fn infinity() -> Self; /// Returns the negative infinite value. fn neg_infinity() -> Self; + /// Returns the `0` value. + fn zero() -> Self; /// Returns -0.0. fn neg_zero() -> Self; + /// Returns the `1` value. + fn one() -> Self; /// Returns true if this value is NaN and false otherwise. fn is_nan(self) -> bool; @@ -1464,8 +1255,12 @@ pub trait Float: Signed + Primitive { fn min_10_exp(unused_self: Option) -> int; /// Returns the maximum base-10 exponent that this type can represent. fn max_10_exp(unused_self: Option) -> int; + /// Returns the smallest finite value that this type can represent. + fn min_value() -> Self; /// Returns the smallest normalized positive number that this type can represent. fn min_pos_value(unused_self: Option) -> Self; + /// Returns the largest finite value that this type can represent. + fn max_value() -> Self; /// Returns the mantissa, exponent and sign as integers, respectively. fn integer_decode(self) -> (u64, i16, i8); @@ -1482,6 +1277,22 @@ pub trait Float: Signed + Primitive { /// Return the fractional part of a number. fn fract(self) -> Self; + /// Computes the absolute value of `self`. Returns `Float::nan()` if the + /// number is `Float::nan()`. + fn abs(self) -> Self; + /// Returns a number that represents the sign of `self`. + /// + /// - `1.0` if the number is positive, `+0.0` or `Float::infinity()` + /// - `-1.0` if the number is negative, `-0.0` or `Float::neg_infinity()` + /// - `Float::nan()` if the number is `Float::nan()` + fn signum(self) -> Self; + /// Returns `true` if `self` is positive, including `+0.0` and + /// `Float::infinity()`. + fn is_positive(self) -> bool; + /// Returns `true` if `self` is negative, including `-0.0` and + /// `Float::neg_infinity()`. + fn is_negative(self) -> bool; + /// Fused multiply-add. Computes `(self * a) + b` with only one rounding /// error. This produces a more accurate result with better performance than /// a separate multiplication operation followed by an add. @@ -1560,3 +1371,135 @@ pub trait Float: Signed + Primitive { /// Convert degrees to radians. fn to_radians(self) -> Self; } + +// DEPRECATED + +macro_rules! trait_impl { + ($name:ident for $($t:ty)*) => { + $(#[allow(deprecated)] impl $name for $t {})* + }; +} + +#[deprecated = "Generalised numbers are no longer supported"] +#[allow(deprecated)] +pub trait Num: PartialEq + Zero + One + + Neg + + Add + + Sub + + Mul + + Div + + Rem {} +trait_impl!(Num for uint u8 u16 u32 u64 int i8 i16 i32 i64 f32 f64) + +#[deprecated = "Generalised unsigned numbers are no longer supported"] +#[allow(deprecated)] +pub trait Unsigned: Num {} +trait_impl!(Unsigned for uint u8 u16 u32 u64) + +#[deprecated = "Use `Float` or `Int`"] +#[allow(deprecated)] +pub trait Primitive: Copy + Clone + Num + NumCast + PartialOrd {} +trait_impl!(Primitive for uint u8 u16 u32 u64 int i8 i16 i32 i64 f32 f64) + +#[deprecated = "The generic `Zero` trait will be removed soon."] +pub trait Zero: Add { + #[deprecated = "Use `Int::zero()` or `Float::zero()`."] + fn zero() -> Self; + #[deprecated = "Use `x == Int::zero()` or `x == Float::zero()`."] + fn is_zero(&self) -> bool; +} +#[deprecated = "Use `Int::zero()` or `Float::zero()`."] +#[allow(deprecated)] +pub fn zero() -> T { Zero::zero() } +macro_rules! zero_impl { + ($t:ty, $v:expr) => { + impl Zero for $t { + fn zero() -> $t { $v } + fn is_zero(&self) -> bool { *self == $v } + } + } +} +zero_impl!(uint, 0u) +zero_impl!(u8, 0u8) +zero_impl!(u16, 0u16) +zero_impl!(u32, 0u32) +zero_impl!(u64, 0u64) +zero_impl!(int, 0i) +zero_impl!(i8, 0i8) +zero_impl!(i16, 0i16) +zero_impl!(i32, 0i32) +zero_impl!(i64, 0i64) +zero_impl!(f32, 0.0f32) +zero_impl!(f64, 0.0f64) + +#[deprecated = "The generic `One` trait will be removed soon."] +pub trait One: Mul { + #[deprecated = "Use `Int::one()` or `Float::one()`."] + fn one() -> Self; +} +#[deprecated = "Use `Int::one()` or `Float::one()`."] +#[allow(deprecated)] +pub fn one() -> T { One::one() } +macro_rules! one_impl { + ($t:ty, $v:expr) => { + impl One for $t { + fn one() -> $t { $v } + } + } +} +one_impl!(uint, 1u) +one_impl!(u8, 1u8) +one_impl!(u16, 1u16) +one_impl!(u32, 1u32) +one_impl!(u64, 1u64) +one_impl!(int, 1i) +one_impl!(i8, 1i8) +one_impl!(i16, 1i16) +one_impl!(i32, 1i32) +one_impl!(i64, 1i64) +one_impl!(f32, 1.0f32) +one_impl!(f64, 1.0f64) + +#[deprecated = "Use `UnsignedInt::next_power_of_two`"] +pub fn next_power_of_two(n: T) -> T { + n.next_power_of_two() +} +#[deprecated = "Use `UnsignedInt::is_power_of_two`"] +pub fn is_power_of_two(n: T) -> bool { + n.is_power_of_two() +} +#[deprecated = "Use `UnsignedInt::checked_next_power_of_two`"] +pub fn checked_next_power_of_two(n: T) -> Option { + n.checked_next_power_of_two() +} + +#[deprecated = "Generalised bounded values are no longer supported"] +pub trait Bounded { + #[deprecated = "Use `Int::min_value` or `Float::min_value`"] + fn min_value() -> Self; + #[deprecated = "Use `Int::max_value` or `Float::max_value`"] + fn max_value() -> Self; +} +macro_rules! bounded_impl { + ($T:ty, $min:expr, $max:expr) => { + impl Bounded for $T { + #[inline] + fn min_value() -> $T { $min } + + #[inline] + fn max_value() -> $T { $max } + } + }; +} +bounded_impl!(uint, uint::MIN, uint::MAX) +bounded_impl!(u8, u8::MIN, u8::MAX) +bounded_impl!(u16, u16::MIN, u16::MAX) +bounded_impl!(u32, u32::MIN, u32::MAX) +bounded_impl!(u64, u64::MIN, u64::MAX) +bounded_impl!(int, int::MIN, int::MAX) +bounded_impl!(i8, i8::MIN, i8::MAX) +bounded_impl!(i16, i16::MIN, i16::MAX) +bounded_impl!(i32, i32::MIN, i32::MAX) +bounded_impl!(i64, i64::MIN, i64::MAX) +bounded_impl!(f32, f32::MIN_VALUE, f32::MAX_VALUE) +bounded_impl!(f64, f64::MIN_VALUE, f64::MAX_VALUE) diff --git a/src/libcore/prelude.rs b/src/libcore/prelude.rs index 17f7a04819f4b..60012ab149f2a 100644 --- a/src/libcore/prelude.rs +++ b/src/libcore/prelude.rs @@ -51,9 +51,7 @@ pub use cmp::{Ordering, Less, Equal, Greater, Equiv}; pub use iter::{FromIterator, Extend}; pub use iter::{Iterator, DoubleEndedIterator, RandomAccessIterator, CloneableIterator}; pub use iter::{OrdIterator, MutableDoubleEndedIterator, ExactSize}; -pub use num::{Num, NumCast, CheckedAdd, CheckedSub, CheckedMul}; -pub use num::{Signed, Unsigned, Float}; -pub use num::{Primitive, Int, ToPrimitive, FromPrimitive}; +pub use num::{ToPrimitive, FromPrimitive}; pub use option::{Option, Some, None}; pub use ptr::RawPtr; pub use result::{Result, Ok, Err}; diff --git a/src/libcore/slice.rs b/src/libcore/slice.rs index 138422ceff1ce..7b223dc501beb 100644 --- a/src/libcore/slice.rs +++ b/src/libcore/slice.rs @@ -40,7 +40,7 @@ use cmp::{PartialEq, PartialOrd, Eq, Ord, Ordering, Less, Equal, Greater, Equiv} use cmp; use default::Default; use iter::*; -use num::{CheckedAdd, Saturating, div_rem}; +use num::{Int, div_rem}; use ops; use option::{None, Option, Some}; use ptr; @@ -1346,7 +1346,7 @@ impl<'a, T> Iterator<&'a [T]> for Windows<'a, T> { (0, Some(0)) } else { let x = self.v.len() - self.size; - (x.saturating_add(1), x.checked_add(&1u)) + (x.saturating_add(1), x.checked_add(1u)) } } } diff --git a/src/libcore/str.rs b/src/libcore/str.rs index 4c1bfb6170907..b3bed201598d8 100644 --- a/src/libcore/str.rs +++ b/src/libcore/str.rs @@ -25,7 +25,7 @@ use iter::{Map, Iterator}; use iter::{DoubleEndedIterator, ExactSize}; use iter::range; use kinds::Sized; -use num::{CheckedMul, Saturating}; +use num::Int; use option::{Option, None, Some}; use raw::Repr; use slice::{mod, SlicePrelude}; @@ -750,7 +750,7 @@ impl<'a> Iterator for Utf16CodeUnits<'a> { // every char gets either one u16 or two u16, // so this iterator is between 1 or 2 times as // long as the underlying iterator. - (low, high.and_then(|n| n.checked_mul(&2))) + (low, high.and_then(|n| n.checked_mul(2))) } } diff --git a/src/libcoretest/cmp.rs b/src/libcoretest/cmp.rs index 59ce73fe40da5..716300f652d67 100644 --- a/src/libcoretest/cmp.rs +++ b/src/libcoretest/cmp.rs @@ -109,6 +109,8 @@ fn test_partial_max() { #[test] fn test_user_defined_eq() { + use core::num::SignedInt; + // Our type. struct SketchyNum { num : int diff --git a/src/libcoretest/iter.rs b/src/libcoretest/iter.rs index aeab18ca05e30..7764fb26c11c4 100644 --- a/src/libcoretest/iter.rs +++ b/src/libcoretest/iter.rs @@ -10,9 +10,9 @@ use core::iter::*; use core::iter::order::*; +use core::num::SignedInt; use core::uint; use core::cmp; -use core::num; use core::ops::Slice; use test::Bencher; @@ -689,50 +689,6 @@ fn test_double_ended_range() { #[test] fn test_range() { - /// A mock type to check Range when ToPrimitive returns None - struct Foo; - - impl ToPrimitive for Foo { - fn to_i64(&self) -> Option { None } - fn to_u64(&self) -> Option { None } - } - - impl Add for Foo { - fn add(&self, _: &Foo) -> Foo { - Foo - } - } - - impl PartialEq for Foo { - fn eq(&self, _: &Foo) -> bool { - true - } - } - - impl PartialOrd for Foo { - fn partial_cmp(&self, _: &Foo) -> Option { - None - } - } - - impl Clone for Foo { - fn clone(&self) -> Foo { - Foo - } - } - - impl Mul for Foo { - fn mul(&self, _: &Foo) -> Foo { - Foo - } - } - - impl num::One for Foo { - fn one() -> Foo { - Foo - } - } - assert!(range(0i, 5).collect::>() == vec![0i, 1, 2, 3, 4]); assert!(range(-10i, -1).collect::>() == vec![-10, -9, -8, -7, -6, -5, -4, -3, -2]); @@ -746,7 +702,6 @@ fn test_range() { // this test is only meaningful when sizeof uint < sizeof u64 assert_eq!(range(uint::MAX - 1, uint::MAX).size_hint(), (1, Some(1))); assert_eq!(range(-10i, -1).size_hint(), (9, Some(9))); - assert_eq!(range(Foo, Foo).size_hint(), (0, None)); } #[test] diff --git a/src/libcoretest/num/int_macros.rs b/src/libcoretest/num/int_macros.rs index f74f503383b7d..5e2530ef2a92b 100644 --- a/src/libcoretest/num/int_macros.rs +++ b/src/libcoretest/num/int_macros.rs @@ -15,8 +15,8 @@ macro_rules! int_module (($T:ty, $T_i:ident) => ( mod tests { use core::$T_i::*; use core::int; + use core::num::{Int, SignedInt}; use num; - use core::num::CheckedDiv; #[test] fn test_overflows() { @@ -37,14 +37,6 @@ mod tests { assert!((-1 as $T).abs() == 1 as $T); } - #[test] - fn test_abs_sub() { - assert!((-1 as $T).abs_sub(&(1 as $T)) == 0 as $T); - assert!((1 as $T).abs_sub(&(1 as $T)) == 0 as $T); - assert!((1 as $T).abs_sub(&(0 as $T)) == 1 as $T); - assert!((1 as $T).abs_sub(&(-1 as $T)) == 2 as $T); - } - #[test] fn test_signum() { assert!((1 as $T).signum() == 1 as $T); @@ -160,9 +152,9 @@ mod tests { #[test] fn test_signed_checked_div() { - assert!(10i.checked_div(&2) == Some(5)); - assert!(5i.checked_div(&0) == None); - assert!(int::MIN.checked_div(&-1) == None); + assert!(10i.checked_div(2) == Some(5)); + assert!(5i.checked_div(0) == None); + assert!(int::MIN.checked_div(-1) == None); } } diff --git a/src/libcoretest/num/mod.rs b/src/libcoretest/num/mod.rs index 8bb238c0b66e8..38502321c1d21 100644 --- a/src/libcoretest/num/mod.rs +++ b/src/libcoretest/num/mod.rs @@ -8,7 +8,10 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::num::cast; +use core::cmp::PartialEq; +use core::fmt::Show; +use core::num::{NumCast, cast}; +use core::ops::{Add, Sub, Mul, Div, Rem}; mod int_macros; mod i8; @@ -24,7 +27,12 @@ mod u64; mod uint; /// Helper function for testing numeric operations -pub fn test_num(ten: T, two: T) { +pub fn test_num(ten: T, two: T) where + T: PartialEq + NumCast + + Add + Sub + + Mul + Div + + Rem + Show +{ assert_eq!(ten.add(&two), cast(12i).unwrap()); assert_eq!(ten.sub(&two), cast(8i).unwrap()); assert_eq!(ten.mul(&two), cast(20i).unwrap()); diff --git a/src/libcoretest/num/uint_macros.rs b/src/libcoretest/num/uint_macros.rs index e59e2378ba242..01a88119b6470 100644 --- a/src/libcoretest/num/uint_macros.rs +++ b/src/libcoretest/num/uint_macros.rs @@ -14,8 +14,8 @@ macro_rules! uint_module (($T:ty, $T_i:ident) => ( #[cfg(test)] mod tests { use core::$T_i::*; + use core::num::Int; use num; - use core::num::CheckedDiv; #[test] fn test_overflows() { @@ -120,8 +120,8 @@ mod tests { #[test] fn test_unsigned_checked_div() { - assert!(10u.checked_div(&2) == Some(5)); - assert!(5u.checked_div(&0) == None); + assert!(10u.checked_div(2) == Some(5)); + assert!(5u.checked_div(0) == None); } } )) diff --git a/src/librand/chacha.rs b/src/librand/chacha.rs index 97e68bcbb2c6c..2693f18364430 100644 --- a/src/librand/chacha.rs +++ b/src/librand/chacha.rs @@ -11,6 +11,7 @@ //! The ChaCha random number generator. use core::prelude::*; +use core::num::Int; use {Rng, SeedableRng, Rand}; diff --git a/src/librand/distributions/mod.rs b/src/librand/distributions/mod.rs index 6606031989151..7d54422601b77 100644 --- a/src/librand/distributions/mod.rs +++ b/src/librand/distributions/mod.rs @@ -23,7 +23,7 @@ that do not need to record state. #![experimental] use core::prelude::*; -use core::num; +use core::num::{Float, Int}; use {Rng, Rand}; @@ -127,7 +127,7 @@ impl<'a, T: Clone> WeightedChoice<'a, T> { // weights so we can binary search. This *could* drop elements // with weight == 0 as an optimisation. for item in items.iter_mut() { - running_total = match running_total.checked_add(&item.weight) { + running_total = match running_total.checked_add(item.weight) { Some(n) => n, None => panic!("WeightedChoice::new called with a total weight \ larger than a uint can contain") @@ -243,7 +243,7 @@ fn ziggurat( let u = if symmetric {2.0 * f - 1.0} else {f}; let x = u * x_tab[i]; - let test_x = if symmetric {num::abs(x)} else {x}; + let test_x = if symmetric { x.abs() } else {x}; // algebraically equivalent to |u| < x_tab[i+1]/x_tab[i] (or u < x_tab[i+1]/x_tab[i]) if test_x < x_tab[i + 1] { diff --git a/src/librand/distributions/range.rs b/src/librand/distributions/range.rs index 2e048cb029d4a..03270ff3c6013 100644 --- a/src/librand/distributions/range.rs +++ b/src/librand/distributions/range.rs @@ -13,7 +13,7 @@ // this is surprisingly complicated to be both generic & correct use core::prelude::*; -use core::num::Bounded; +use core::num::Int; use Rng; use distributions::{Sample, IndependentSample}; @@ -98,7 +98,7 @@ macro_rules! integer_impl { fn construct_range(low: $ty, high: $ty) -> Range<$ty> { let range = high as $unsigned - low as $unsigned; - let unsigned_max: $unsigned = Bounded::max_value(); + let unsigned_max: $unsigned = Int::max_value(); // this is the largest number that fits into $unsigned // that `range` divides evenly, so, if we've sampled @@ -163,10 +163,10 @@ float_impl! { f64 } #[cfg(test)] mod tests { + use std::num::Int; use std::prelude::*; use distributions::{Sample, IndependentSample}; use super::Range; - use std::num::Bounded; #[should_fail] #[test] @@ -187,7 +187,7 @@ mod tests { $( let v: &[($ty, $ty)] = [(0, 10), (10, 127), - (Bounded::min_value(), Bounded::max_value())]; + (Int::min_value(), Int::max_value())]; for &(low, high) in v.iter() { let mut sampler: Range<$ty> = Range::new(low, high); for _ in range(0u, 1000) { diff --git a/src/librbml/lib.rs b/src/librbml/lib.rs index 1dfc0d970a91c..90cd7920e688c 100644 --- a/src/librbml/lib.rs +++ b/src/librbml/lib.rs @@ -114,10 +114,11 @@ pub enum Error { pub mod reader { use std::char; - use std::mem::transmute; use std::int; - use std::option::{None, Option, Some}; use std::io::extensions::u64_from_be_bytes; + use std::mem::transmute; + use std::num::Int; + use std::option::{None, Option, Some}; use serialize; diff --git a/src/librustc/back/lto.rs b/src/librustc/back/lto.rs index 58db79f41ca4c..3fbf830485b28 100644 --- a/src/librustc/back/lto.rs +++ b/src/librustc/back/lto.rs @@ -23,6 +23,7 @@ use flate; use std::iter; use std::mem; +use std::num::Int; pub fn run(sess: &session::Session, llmod: ModuleRef, tm: TargetMachineRef, reachable: &[String]) { diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index 3026e047626a8..055a4c5dff4de 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -37,6 +37,7 @@ use lint::{Context, LintPass, LintArray}; use std::cmp; use std::collections::hash_map::{Occupied, Vacant}; +use std::num::SignedInt; use std::slice; use std::{i8, i16, i32, i64, u8, u16, u32, u64, f32, f64}; use syntax::abi; diff --git a/src/librustc/middle/check_match.rs b/src/librustc/middle/check_match.rs index 4dcd5d8873ea4..a893f8e89598d 100644 --- a/src/librustc/middle/check_match.rs +++ b/src/librustc/middle/check_match.rs @@ -21,6 +21,7 @@ use middle::ty; use std::fmt; use std::iter::AdditiveIterator; use std::iter::range_inclusive; +use std::num::Float; use std::slice; use syntax::ast::*; use syntax::ast_util::walk_pat; diff --git a/src/librustc/middle/trans/type_of.rs b/src/librustc/middle/trans/type_of.rs index d1b8f767bc850..a597325015c70 100644 --- a/src/librustc/middle/trans/type_of.rs +++ b/src/librustc/middle/trans/type_of.rs @@ -21,18 +21,17 @@ use util::ppaux::Repr; use middle::trans::type_::Type; +use std::num::Int; use syntax::abi; use syntax::ast; -use std::num::CheckedMul; - // LLVM doesn't like objects that are too big. Issue #17913 fn ensure_array_fits_in_address_space(ccx: &CrateContext, llet: Type, size: machine::llsize, scapegoat: ty::t) { let esz = machine::llsize_of_alloc(ccx, llet); - match esz.checked_mul(&size) { + match esz.checked_mul(size) { Some(n) if n < ccx.max_obj_size() => {} _ => { ccx.report_overbig_object(scapegoat) } } diff --git a/src/librustc_back/sha2.rs b/src/librustc_back/sha2.rs index 96a15213c5ed6..4319cd791b84f 100644 --- a/src/librustc_back/sha2.rs +++ b/src/librustc_back/sha2.rs @@ -15,7 +15,7 @@ #![allow(deprecated)] // to_be32 use std::iter::range_step; -use std::num::Zero; +use std::num::Int; use std::slice::bytes::{MutableByteVector, copy_memory}; use serialize::hex::ToHex; @@ -61,14 +61,14 @@ impl ToBits for u64 { /// Adds the specified number of bytes to the bit count. panic!() if this would cause numeric /// overflow. -fn add_bytes_to_bits(bits: T, bytes: T) -> T { +fn add_bytes_to_bits(bits: T, bytes: T) -> T { let (new_high_bits, new_low_bits) = bytes.to_bits(); - if new_high_bits > Zero::zero() { + if new_high_bits > Int::zero() { panic!("numeric overflow occurred.") } - match bits.checked_add(&new_low_bits) { + match bits.checked_add(new_low_bits) { Some(x) => return x, None => panic!("numeric overflow occurred.") } @@ -528,10 +528,10 @@ mod tests { extern crate rand; use super::{Digest, Sha256, FixedBuffer}; - use std::num::Bounded; use self::rand::isaac::IsaacRng; use self::rand::Rng; use serialize::hex::FromHex; + use std::num::Int; // A normal addition - no overflow occurs #[test] @@ -543,7 +543,7 @@ mod tests { #[test] #[should_fail] fn test_add_bytes_to_bits_overflow() { - super::add_bytes_to_bits::(Bounded::max_value(), 1); + super::add_bytes_to_bits::(Int::max_value(), 1); } struct Test { diff --git a/src/librustdoc/stability_summary.rs b/src/librustdoc/stability_summary.rs index 37eb730819109..b0e1aeea3a182 100644 --- a/src/librustdoc/stability_summary.rs +++ b/src/librustdoc/stability_summary.rs @@ -15,7 +15,6 @@ use std::ops::Add; use std::num::Zero; -use std::iter::AdditiveIterator; use syntax::attr::{Deprecated, Experimental, Unstable, Stable, Frozen, Locked}; use syntax::ast::Public; @@ -55,6 +54,18 @@ impl Add for Counts { } impl Counts { + fn zero() -> Counts { + Counts { + deprecated: 0, + experimental: 0, + unstable: 0, + stable: 0, + frozen: 0, + locked: 0, + unmarked: 0, + } + } + pub fn total(&self) -> uint { self.deprecated + self.experimental + self.unstable + self.stable + self.frozen + self.locked + self.unmarked @@ -92,14 +103,14 @@ fn visible(item: &Item) -> bool { fn count_stability(stab: Option<&Stability>) -> Counts { match stab { - None => Counts { unmarked: 1, .. Zero::zero() }, + None => Counts { unmarked: 1, .. Counts::zero() }, Some(ref stab) => match stab.level { - Deprecated => Counts { deprecated: 1, .. Zero::zero() }, - Experimental => Counts { experimental: 1, .. Zero::zero() }, - Unstable => Counts { unstable: 1, .. Zero::zero() }, - Stable => Counts { stable: 1, .. Zero::zero() }, - Frozen => Counts { frozen: 1, .. Zero::zero() }, - Locked => Counts { locked: 1, .. Zero::zero() }, + Deprecated => Counts { deprecated: 1, .. Counts::zero() }, + Experimental => Counts { experimental: 1, .. Counts::zero() }, + Unstable => Counts { unstable: 1, .. Counts::zero() }, + Stable => Counts { stable: 1, .. Counts::zero() }, + Frozen => Counts { frozen: 1, .. Counts::zero() }, + Locked => Counts { locked: 1, .. Counts::zero() }, } } } @@ -108,15 +119,19 @@ fn summarize_methods(item: &Item) -> Counts { match cache_key.get().unwrap().impls.get(&item.def_id) { Some(v) => { v.iter().map(|i| { - let mut count = count_stability(i.stability.as_ref()); + let count = count_stability(i.stability.as_ref()); if i.impl_.trait_.is_none() { - count = count + - i.impl_.items.iter().map(|ti| summarize_item(ti).0).sum(); + count + i.impl_.items.iter() + .map(|ti| summarize_item(ti).0) + .fold(Counts::zero(), |acc, c| acc + c) + } else { + count } - count - }).sum() - } - None => Zero::zero() + }).fold(Counts::zero(), |acc, c| acc + c) + }, + None => { + Counts::zero() + }, } } @@ -136,14 +151,14 @@ fn summarize_item(item: &Item) -> (Counts, Option) { let subcounts = subitems.iter().filter(|i| visible(*i)) .map(summarize_item) .map(|s| s.val0()) - .sum(); + .fold(Counts::zero(), |acc, x| acc + x); (item_counts + subcounts, None) } // `pub` automatically EnumItem(Enum { variants: ref subitems, .. }) => { let subcounts = subitems.iter().map(summarize_item) .map(|s| s.val0()) - .sum(); + .fold(Counts::zero(), |acc, x| acc + x); (item_counts + subcounts, None) } TraitItem(Trait { @@ -161,7 +176,7 @@ fn summarize_item(item: &Item) -> (Counts, Option) { .map(extract_item) .map(summarize_item) .map(|s| s.val0()) - .sum(); + .fold(Counts::zero(), |acc, x| acc + x); (item_counts + subcounts, None) } ModuleItem(Module { ref items, .. }) => { @@ -182,7 +197,7 @@ fn summarize_item(item: &Item) -> (Counts, Option) { })) } // no stability information for the following items: - ViewItemItem(_) | PrimitiveItem(_) => (Zero::zero(), None), + ViewItemItem(_) | PrimitiveItem(_) => (Counts::zero(), None), _ => (item_counts, None) } } @@ -192,7 +207,7 @@ pub fn build(krate: &Crate) -> ModuleSummary { match krate.module { None => ModuleSummary { name: krate.name.clone(), - counts: Zero::zero(), + counts: Counts::zero(), submodules: Vec::new(), }, Some(ref item) => ModuleSummary { diff --git a/src/libserialize/json.rs b/src/libserialize/json.rs index 7731351758558..626535f989ef6 100644 --- a/src/libserialize/json.rs +++ b/src/libserialize/json.rs @@ -199,7 +199,7 @@ use std::collections::{HashMap, TreeMap}; use std::{char, f64, fmt, io, num, str}; use std::io::MemWriter; use std::mem::{swap, transmute}; -use std::num::{FPNaN, FPInfinite}; +use std::num::{Float, FPNaN, FPInfinite, Int}; use std::str::ScalarValue; use std::string; use std::vec::Vec; @@ -609,7 +609,7 @@ impl<'a> PrettyEncoder<'a> { /// This is safe to set during encoding. pub fn set_indent<'a>(&mut self, indent: uint) { // self.indent very well could be 0 so we need to use checked division. - let level = self.curr_indent.checked_div(&self.indent).unwrap_or(0); + let level = self.curr_indent.checked_div(self.indent).unwrap_or(0); self.indent = indent; self.curr_indent = level * self.indent; } @@ -1522,7 +1522,7 @@ impl> Parser { } } - let exp = num::pow(10_f64, exp); + let exp = 10_f64.powi(exp as i32); if neg_exp { res /= exp; } else { @@ -2455,6 +2455,7 @@ mod tests { TrailingCharacters, TrailingComma}; use std::{i64, u64, f32, f64, io}; use std::collections::TreeMap; + use std::num::Float; use std::string; #[deriving(Decodable, Eq, PartialEq, Show)] diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs index f55ce9ba4625c..68c428f456db2 100644 --- a/src/libstd/collections/hash/map.rs +++ b/src/libstd/collections/hash/map.rs @@ -18,7 +18,7 @@ use hash::{Hash, Hasher, RandomSipHasher}; use iter::{mod, Iterator, FromIterator, Extend}; use kinds::Sized; use mem::{mod, replace}; -use num; +use num::UnsignedInt; use ops::{Deref, Index, IndexMut}; use option::{Some, None, Option}; use result::{Result, Ok, Err}; @@ -549,7 +549,7 @@ impl, V, S, H: Hasher> HashMap { /// ``` #[inline] pub fn with_capacity_and_hasher(capacity: uint, hasher: H) -> HashMap { - let cap = num::next_power_of_two(max(INITIAL_CAPACITY, capacity)); + let cap = max(INITIAL_CAPACITY, capacity).next_power_of_two(); HashMap { hasher: hasher, resize_policy: DefaultResizePolicy::new(cap), @@ -572,8 +572,7 @@ impl, V, S, H: Hasher> HashMap { /// map.reserve(10); /// ``` pub fn reserve(&mut self, new_minimum_capacity: uint) { - let cap = num::next_power_of_two( - max(INITIAL_CAPACITY, new_minimum_capacity)); + let cap = max(INITIAL_CAPACITY, new_minimum_capacity).next_power_of_two(); self.resize_policy.reserve(cap); @@ -588,7 +587,7 @@ impl, V, S, H: Hasher> HashMap { /// 2) Ensure new_capacity is a power of two. fn resize(&mut self, new_capacity: uint) { assert!(self.table.size() <= new_capacity); - assert!(num::is_power_of_two(new_capacity)); + assert!(new_capacity.is_power_of_two()); let mut old_table = replace(&mut self.table, RawTable::new(new_capacity)); let old_size = old_table.size(); diff --git a/src/libstd/collections/hash/table.rs b/src/libstd/collections/hash/table.rs index fd964cdf02c53..dd65a00d110b9 100644 --- a/src/libstd/collections/hash/table.rs +++ b/src/libstd/collections/hash/table.rs @@ -17,7 +17,7 @@ use iter::{Iterator, count}; use kinds::{Sized, marker}; use mem::{min_align_of, size_of}; use mem; -use num::{CheckedAdd, CheckedMul, is_power_of_two}; +use num::{Int, UnsignedInt}; use ops::{Deref, DerefMut, Drop}; use option::{Some, None, Option}; use ptr::{RawPtr, copy_nonoverlapping_memory, zero_memory}; @@ -516,7 +516,7 @@ impl>> GapThenFull { /// /// Fails if `target_alignment` is not a power of two. fn round_up_to_next(unrounded: uint, target_alignment: uint) -> uint { - assert!(is_power_of_two(target_alignment)); + assert!(target_alignment.is_power_of_two()); (unrounded + target_alignment - 1) & !(target_alignment - 1) } @@ -604,9 +604,9 @@ impl RawTable { vals_size, min_align_of::< V >()); // One check for overflow that covers calculation and rounding of size. - let size_of_bucket = size_of::().checked_add(&size_of::()).unwrap() - .checked_add(&size_of::()).unwrap(); - assert!(size >= capacity.checked_mul(&size_of_bucket) + let size_of_bucket = size_of::().checked_add(size_of::()).unwrap() + .checked_add(size_of::()).unwrap(); + assert!(size >= capacity.checked_mul(size_of_bucket) .expect("capacity overflow"), "capacity overflow"); diff --git a/src/libstd/fmt.rs b/src/libstd/fmt.rs index 782ef098d81eb..eb81935a8c903 100644 --- a/src/libstd/fmt.rs +++ b/src/libstd/fmt.rs @@ -190,6 +190,7 @@ like: ```rust use std::fmt; use std::f64; +use std::num::Float; struct Vector2D { x: int, diff --git a/src/libstd/num/f32.rs b/src/libstd/num/f32.rs index 63c3956ef2412..3f46cc8af50b1 100644 --- a/src/libstd/num/f32.rs +++ b/src/libstd/num/f32.rs @@ -20,6 +20,7 @@ use prelude::*; use from_str::FromStr; use intrinsics; use libc::c_int; +use num::{Float, FloatMath}; use num::strconv; use num; @@ -108,6 +109,11 @@ impl FloatMath for f32 { unsafe { cmath::fminf(self, other) } } + #[inline] + fn abs_sub(self, other: f32) -> f32 { + unsafe { cmath::fdimf(self, other) } + } + #[inline] fn cbrt(self) -> f32 { unsafe { cmath::cbrtf(self) } @@ -593,20 +599,20 @@ mod tests { #[test] fn test_abs_sub() { - assert_eq!((-1f32).abs_sub(&1f32), 0f32); - assert_eq!(1f32.abs_sub(&1f32), 0f32); - assert_eq!(1f32.abs_sub(&0f32), 1f32); - assert_eq!(1f32.abs_sub(&-1f32), 2f32); - assert_eq!(NEG_INFINITY.abs_sub(&0f32), 0f32); - assert_eq!(INFINITY.abs_sub(&1f32), INFINITY); - assert_eq!(0f32.abs_sub(&NEG_INFINITY), INFINITY); - assert_eq!(0f32.abs_sub(&INFINITY), 0f32); + assert_eq!((-1f32).abs_sub(1f32), 0f32); + assert_eq!(1f32.abs_sub(1f32), 0f32); + assert_eq!(1f32.abs_sub(0f32), 1f32); + assert_eq!(1f32.abs_sub(-1f32), 2f32); + assert_eq!(NEG_INFINITY.abs_sub(0f32), 0f32); + assert_eq!(INFINITY.abs_sub(1f32), INFINITY); + assert_eq!(0f32.abs_sub(NEG_INFINITY), INFINITY); + assert_eq!(0f32.abs_sub(INFINITY), 0f32); } #[test] fn test_abs_sub_nowin() { - assert!(NAN.abs_sub(&-1f32).is_nan()); - assert!(1f32.abs_sub(&NAN).is_nan()); + assert!(NAN.abs_sub(-1f32).is_nan()); + assert!(1f32.abs_sub(NAN).is_nan()); } #[test] @@ -650,7 +656,7 @@ mod tests { let nan: f32 = Float::nan(); let inf: f32 = Float::infinity(); let neg_inf: f32 = Float::neg_infinity(); - let zero: f32 = Zero::zero(); + let zero: f32 = Float::zero(); let neg_zero: f32 = Float::neg_zero(); assert!(!nan.is_normal()); assert!(!inf.is_normal()); @@ -667,7 +673,7 @@ mod tests { let nan: f32 = Float::nan(); let inf: f32 = Float::infinity(); let neg_inf: f32 = Float::neg_infinity(); - let zero: f32 = Zero::zero(); + let zero: f32 = Float::zero(); let neg_zero: f32 = Float::neg_zero(); assert_eq!(nan.classify(), FPNaN); assert_eq!(inf.classify(), FPInfinite); diff --git a/src/libstd/num/f64.rs b/src/libstd/num/f64.rs index 6e8e92eb91d03..4d691fc967698 100644 --- a/src/libstd/num/f64.rs +++ b/src/libstd/num/f64.rs @@ -19,6 +19,7 @@ use prelude::*; use from_str::FromStr; use intrinsics; use libc::c_int; +use num::{Float, FloatMath}; use num::strconv; use num; @@ -116,6 +117,11 @@ impl FloatMath for f64 { unsafe { cmath::fmin(self, other) } } + #[inline] + fn abs_sub(self, other: f64) -> f64 { + unsafe { cmath::fdim(self, other) } + } + #[inline] fn cbrt(self) -> f64 { unsafe { cmath::cbrt(self) } @@ -591,20 +597,20 @@ mod tests { #[test] fn test_abs_sub() { - assert_eq!((-1f64).abs_sub(&1f64), 0f64); - assert_eq!(1f64.abs_sub(&1f64), 0f64); - assert_eq!(1f64.abs_sub(&0f64), 1f64); - assert_eq!(1f64.abs_sub(&-1f64), 2f64); - assert_eq!(NEG_INFINITY.abs_sub(&0f64), 0f64); - assert_eq!(INFINITY.abs_sub(&1f64), INFINITY); - assert_eq!(0f64.abs_sub(&NEG_INFINITY), INFINITY); - assert_eq!(0f64.abs_sub(&INFINITY), 0f64); + assert_eq!((-1f64).abs_sub(1f64), 0f64); + assert_eq!(1f64.abs_sub(1f64), 0f64); + assert_eq!(1f64.abs_sub(0f64), 1f64); + assert_eq!(1f64.abs_sub(-1f64), 2f64); + assert_eq!(NEG_INFINITY.abs_sub(0f64), 0f64); + assert_eq!(INFINITY.abs_sub(1f64), INFINITY); + assert_eq!(0f64.abs_sub(NEG_INFINITY), INFINITY); + assert_eq!(0f64.abs_sub(INFINITY), 0f64); } #[test] fn test_abs_sub_nowin() { - assert!(NAN.abs_sub(&-1f64).is_nan()); - assert!(1f64.abs_sub(&NAN).is_nan()); + assert!(NAN.abs_sub(-1f64).is_nan()); + assert!(1f64.abs_sub(NAN).is_nan()); } #[test] @@ -648,7 +654,7 @@ mod tests { let nan: f64 = Float::nan(); let inf: f64 = Float::infinity(); let neg_inf: f64 = Float::neg_infinity(); - let zero: f64 = Zero::zero(); + let zero: f64 = Float::zero(); let neg_zero: f64 = Float::neg_zero(); assert!(!nan.is_normal()); assert!(!inf.is_normal()); @@ -665,7 +671,7 @@ mod tests { let nan: f64 = Float::nan(); let inf: f64 = Float::infinity(); let neg_inf: f64 = Float::neg_infinity(); - let zero: f64 = Zero::zero(); + let zero: f64 = Float::zero(); let neg_zero: f64 = Float::neg_zero(); assert_eq!(nan.classify(), FPNaN); assert_eq!(inf.classify(), FPInfinite); diff --git a/src/libstd/num/float_macros.rs b/src/libstd/num/float_macros.rs index 519de85edde65..4b3727ead6148 100644 --- a/src/libstd/num/float_macros.rs +++ b/src/libstd/num/float_macros.rs @@ -14,6 +14,7 @@ macro_rules! assert_approx_eq( ($a:expr, $b:expr) => ({ + use num::Float; let (a, b) = (&$a, &$b); assert!((*a - *b).abs() < 1.0e-6, "{} is not approximately equal to {}", *a, *b); diff --git a/src/libstd/num/mod.rs b/src/libstd/num/mod.rs index ffe162cbc64fc..0afc8ce0452c8 100644 --- a/src/libstd/num/mod.rs +++ b/src/libstd/num/mod.rs @@ -18,13 +18,13 @@ use option::Option; +#[cfg(test)] use cmp::PartialEq; #[cfg(test)] use fmt::Show; +#[cfg(test)] use ops::{Add, Sub, Mul, Div, Rem}; pub use core::num::{Num, div_rem, Zero, zero, One, one}; -pub use core::num::{Signed, abs, abs_sub, signum}; pub use core::num::{Unsigned, pow, Bounded}; -pub use core::num::{Primitive, Int, Saturating}; -pub use core::num::{CheckedAdd, CheckedSub, CheckedMul, CheckedDiv}; +pub use core::num::{Primitive, Int, SignedInt, UnsignedInt}; pub use core::num::{cast, FromPrimitive, NumCast, ToPrimitive}; pub use core::num::{next_power_of_two, is_power_of_two}; pub use core::num::{checked_next_power_of_two}; @@ -58,6 +58,11 @@ pub trait FloatMath: Float { /// Returns the minimum of the two numbers. fn min(self, other: Self) -> 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. + fn abs_sub(self, other: Self) -> Self; + /// Take the cubic root of a number. fn cbrt(self) -> Self; /// Calculate the length of the hypotenuse of a right-angle triangle given @@ -122,9 +127,21 @@ pub fn from_str_radix(str: &str, radix: uint) -> Option { FromStrRadix::from_str_radix(str, radix) } +// DEPRECATED + +#[deprecated = "Use `FloatMath::abs_sub`"] +pub fn abs_sub(x: T, y: T) -> T { + x.abs_sub(y) +} + /// Helper function for testing numeric operations #[cfg(test)] -pub fn test_num(ten: T, two: T) { +pub fn test_num(ten: T, two: T) where + T: PartialEq + NumCast + + Add + Sub + + Mul + Div + + Rem + Show +{ assert_eq!(ten.add(&two), cast(12i).unwrap()); assert_eq!(ten.sub(&two), cast(8i).unwrap()); assert_eq!(ten.mul(&two), cast(20i).unwrap()); @@ -624,46 +641,46 @@ mod tests { #[test] fn test_checked_add() { let five_less = uint::MAX - 5; - assert_eq!(five_less.checked_add(&0), Some(uint::MAX - 5)); - assert_eq!(five_less.checked_add(&1), Some(uint::MAX - 4)); - assert_eq!(five_less.checked_add(&2), Some(uint::MAX - 3)); - assert_eq!(five_less.checked_add(&3), Some(uint::MAX - 2)); - assert_eq!(five_less.checked_add(&4), Some(uint::MAX - 1)); - assert_eq!(five_less.checked_add(&5), Some(uint::MAX)); - assert_eq!(five_less.checked_add(&6), None); - assert_eq!(five_less.checked_add(&7), None); + assert_eq!(five_less.checked_add(0), Some(uint::MAX - 5)); + assert_eq!(five_less.checked_add(1), Some(uint::MAX - 4)); + assert_eq!(five_less.checked_add(2), Some(uint::MAX - 3)); + assert_eq!(five_less.checked_add(3), Some(uint::MAX - 2)); + assert_eq!(five_less.checked_add(4), Some(uint::MAX - 1)); + assert_eq!(five_less.checked_add(5), Some(uint::MAX)); + assert_eq!(five_less.checked_add(6), None); + assert_eq!(five_less.checked_add(7), None); } #[test] fn test_checked_sub() { - assert_eq!(5u.checked_sub(&0), Some(5)); - assert_eq!(5u.checked_sub(&1), Some(4)); - assert_eq!(5u.checked_sub(&2), Some(3)); - assert_eq!(5u.checked_sub(&3), Some(2)); - assert_eq!(5u.checked_sub(&4), Some(1)); - assert_eq!(5u.checked_sub(&5), Some(0)); - assert_eq!(5u.checked_sub(&6), None); - assert_eq!(5u.checked_sub(&7), None); + assert_eq!(5u.checked_sub(0), Some(5)); + assert_eq!(5u.checked_sub(1), Some(4)); + assert_eq!(5u.checked_sub(2), Some(3)); + assert_eq!(5u.checked_sub(3), Some(2)); + assert_eq!(5u.checked_sub(4), Some(1)); + assert_eq!(5u.checked_sub(5), Some(0)); + assert_eq!(5u.checked_sub(6), None); + assert_eq!(5u.checked_sub(7), None); } #[test] fn test_checked_mul() { let third = uint::MAX / 3; - assert_eq!(third.checked_mul(&0), Some(0)); - assert_eq!(third.checked_mul(&1), Some(third)); - assert_eq!(third.checked_mul(&2), Some(third * 2)); - assert_eq!(third.checked_mul(&3), Some(third * 3)); - assert_eq!(third.checked_mul(&4), None); + assert_eq!(third.checked_mul(0), Some(0)); + assert_eq!(third.checked_mul(1), Some(third)); + assert_eq!(third.checked_mul(2), Some(third * 2)); + assert_eq!(third.checked_mul(3), Some(third * 3)); + assert_eq!(third.checked_mul(4), None); } macro_rules! test_next_power_of_two( ($test_name:ident, $T:ident) => ( fn $test_name() { #![test] - assert_eq!(next_power_of_two::<$T>(0), 0); + assert_eq!((0 as $T).next_power_of_two(), 0); let mut next_power = 1; for i in range::<$T>(1, 40) { - assert_eq!(next_power_of_two(i), next_power); + assert_eq!(i.next_power_of_two(), next_power); if i == next_power { next_power *= 2 } } } @@ -680,15 +697,15 @@ mod tests { ($test_name:ident, $T:ident) => ( fn $test_name() { #![test] - assert_eq!(checked_next_power_of_two::<$T>(0), None); + assert_eq!((0 as $T).checked_next_power_of_two(), None); let mut next_power = 1; for i in range::<$T>(1, 40) { - assert_eq!(checked_next_power_of_two(i), Some(next_power)); + assert_eq!(i.checked_next_power_of_two(), Some(next_power)); if i == next_power { next_power *= 2 } } - assert!(checked_next_power_of_two::<$T>($T::MAX / 2).is_some()); - assert_eq!(checked_next_power_of_two::<$T>($T::MAX - 1), None); - assert_eq!(checked_next_power_of_two::<$T>($T::MAX), None); + assert!(($T::MAX / 2).checked_next_power_of_two().is_some()); + assert_eq!(($T::MAX - 1).checked_next_power_of_two(), None); + assert_eq!($T::MAX.checked_next_power_of_two(), None); } ) ) @@ -760,10 +777,7 @@ mod tests { assert_pow!((3i, 0 ) => 1); assert_pow!((5i, 1 ) => 5); assert_pow!((-4i, 2 ) => 16); - assert_pow!((0.5f64, 5 ) => 0.03125); assert_pow!((8i, 3 ) => 512); - assert_pow!((8.0f64, 5 ) => 32768.0); - assert_pow!((8.5f64, 5 ) => 44370.53125); assert_pow!((2u64, 50) => 1125899906842624); } } diff --git a/src/libstd/num/strconv.rs b/src/libstd/num/strconv.rs index 088ea89818e0f..06d2f0ef028e1 100644 --- a/src/libstd/num/strconv.rs +++ b/src/libstd/num/strconv.rs @@ -17,8 +17,7 @@ use char::Char; use from_str::from_str; use iter::Iterator; use num; -use num::{Int, Bounded}; -use num::{Float, FPNaN, FPInfinite, ToPrimitive}; +use num::{Int, Float, FPNaN, FPInfinite, ToPrimitive}; use option::{None, Option, Some}; use slice::{SlicePrelude, CloneSliceAllocPrelude}; use str::StrPrelude; @@ -95,7 +94,7 @@ pub enum SignFormat { fn int_to_str_bytes_common(num: T, radix: uint, sign: SignFormat, f: |u8|) { assert!(2 <= radix && radix <= 36); - let _0: T = num::zero(); + let _0: T = Int::zero(); let neg = num < _0; let radix_gen: T = num::cast(radix).unwrap(); @@ -117,7 +116,7 @@ fn int_to_str_bytes_common(num: T, radix: uint, sign: SignFormat, f: |u8 // numbers [-35 .. 0] we always have [0 .. 35]. let current_digit_signed = deccum % radix_gen; let current_digit = if current_digit_signed < _0 { - -current_digit_signed + _0 - current_digit_signed } else { current_digit_signed }; @@ -195,8 +194,8 @@ pub fn float_to_str_bytes_common( _ => () } - let _0: T = num::zero(); - let _1: T = num::one(); + let _0: T = Float::zero(); + let _1: T = Float::one(); match num.classify() { FPNaN => { return (b"NaN".to_vec(), true); } @@ -431,8 +430,8 @@ pub fn from_str_radix_float(src: &str, radix: uint) -> Option { "from_str_radix_float: must lie in the range `[2, 36]` - found {}", radix); - let _0: T = num::zero(); - let _1: T = num::one(); + let _0: T = Float::zero(); + let _1: T = Float::one(); let radix_t: T = num::cast(radix as int).unwrap(); // Special values @@ -559,8 +558,8 @@ pub fn from_str_radix_float(src: &str, radix: uint) -> Option { }; match (is_positive, exp) { - (true, Some(exp)) => num::pow(base, exp), - (false, Some(exp)) => _1 / num::pow(base, exp), + (true, Some(exp)) => base.powi(exp as i32), + (false, Some(exp)) => _1 / base.powi(exp as i32), (_, None) => return None, } }, @@ -579,9 +578,9 @@ pub fn from_str_radix_int(src: &str, radix: uint) -> Option { num::cast(x).unwrap() } - let _0: T = num::zero(); - let _1: T = num::one(); - let is_signed = _0 > Bounded::min_value(); + let _0: T = Int::zero(); + let _1: T = Int::one(); + let is_signed = _0 > Int::min_value(); let (is_positive, src) = match src.slice_shift_char() { (Some('-'), src) if is_signed => (false, src), @@ -601,11 +600,11 @@ pub fn from_str_radix_int(src: &str, radix: uint) -> Option { Some(x) => x, None => return None, }; - result = match result.checked_mul(&radix) { + result = match result.checked_mul(radix) { Some(result) => result, None => return None, }; - result = match result.checked_add(&x) { + result = match result.checked_add(x) { Some(result) => result, None => return None, }; @@ -616,11 +615,11 @@ pub fn from_str_radix_int(src: &str, radix: uint) -> Option { Some(x) => x, None => return None, }; - result = match result.checked_mul(&radix) { + result = match result.checked_mul(radix) { Some(result) => result, None => return None, }; - result = match result.checked_sub(&x) { + result = match result.checked_sub(x) { Some(result) => result, None => return None, }; diff --git a/src/libstd/prelude.rs b/src/libstd/prelude.rs index f1090e7512797..158e7a59f6dba 100644 --- a/src/libstd/prelude.rs +++ b/src/libstd/prelude.rs @@ -67,9 +67,7 @@ #[doc(no_inline)] pub use iter::{Iterator, DoubleEndedIterator}; #[doc(no_inline)] pub use iter::{RandomAccessIterator, CloneableIterator}; #[doc(no_inline)] pub use iter::{OrdIterator, MutableDoubleEndedIterator}; -#[doc(no_inline)] pub use num::{Num, NumCast, CheckedAdd, CheckedSub, CheckedMul, CheckedDiv}; -#[doc(no_inline)] pub use num::{Signed, Unsigned, Primitive, Int, Float}; -#[doc(no_inline)] pub use num::{FloatMath, ToPrimitive, FromPrimitive}; +#[doc(no_inline)] pub use num::{ToPrimitive, FromPrimitive}; #[doc(no_inline)] pub use boxed::Box; #[doc(no_inline)] pub use option::{Option, Some, None}; #[doc(no_inline)] pub use path::{GenericPath, Path, PosixPath, WindowsPath}; diff --git a/src/libstd/rand/reader.rs b/src/libstd/rand/reader.rs index c8ed980521542..ab3216e93a09e 100644 --- a/src/libstd/rand/reader.rs +++ b/src/libstd/rand/reader.rs @@ -78,6 +78,7 @@ mod test { use super::ReaderRng; use io::MemReader; + use num::Int; use rand::Rng; #[test] diff --git a/src/libstd/sys/common/mod.rs b/src/libstd/sys/common/mod.rs index d5ac617049759..cacb128faa560 100644 --- a/src/libstd/sys/common/mod.rs +++ b/src/libstd/sys/common/mod.rs @@ -13,9 +13,9 @@ use io::{mod, IoError, IoResult}; use prelude::*; -use num; use sys::{last_error, retry, fs}; use c_str::CString; +use num::Int; use path::BytesContainer; use collections; @@ -57,8 +57,8 @@ pub fn unimpl() -> IoError { } // unix has nonzero values as errors -pub fn mkerr_libc(ret: Int) -> IoResult<()> { - if !ret.is_zero() { +pub fn mkerr_libc(ret: T) -> IoResult<()> { + if ret != Int::zero() { Err(last_error()) } else { Ok(()) diff --git a/src/libstd/sys/common/net.rs b/src/libstd/sys/common/net.rs index 7c44142d93cdb..7bb3c6b0ec95a 100644 --- a/src/libstd/sys/common/net.rs +++ b/src/libstd/sys/common/net.rs @@ -11,6 +11,7 @@ use alloc::arc::Arc; use libc::{mod, c_char, c_int}; use mem; +use num::Int; use ptr::{mod, null, null_mut}; use rt::mutex; use io::net::ip::{SocketAddr, IpAddr, Ipv4Addr, Ipv6Addr}; diff --git a/src/libstd/sys/unix/mod.rs b/src/libstd/sys/unix/mod.rs index de104335d7c77..4db9e8a9df8b5 100644 --- a/src/libstd/sys/unix/mod.rs +++ b/src/libstd/sys/unix/mod.rs @@ -18,6 +18,7 @@ extern crate libc; use num; +use num::{Int, SignedInt}; use prelude::*; use io::{mod, IoResult, IoError}; use sys_common::mkerr_libc; @@ -116,11 +117,11 @@ pub fn decode_error_detailed(errno: i32) -> IoError { } #[inline] -pub fn retry> (f: || -> I) -> I { - let minus_one = -num::one::(); +pub fn retry (f: || -> T) -> T { + let one: T = Int::one(); loop { let n = f(); - if n == minus_one && os::errno() == libc::EINTR as int { } + if n == -one && os::errno() == libc::EINTR as int { } else { return n } } } diff --git a/src/libstd/time/duration.rs b/src/libstd/time/duration.rs index c3adae8cff839..6afeb76b83fbe 100644 --- a/src/libstd/time/duration.rs +++ b/src/libstd/time/duration.rs @@ -15,8 +15,7 @@ use {fmt, i64}; use ops::{Add, Sub, Mul, Div, Neg}; use option::{Option, Some, None}; -use num; -use num::{CheckedAdd, CheckedMul}; +use num::Int; use result::{Result, Ok, Err}; /// The number of nanoseconds in a microsecond. @@ -69,7 +68,7 @@ impl Duration { /// Fails when the duration is out of bounds. #[inline] pub fn weeks(weeks: i64) -> Duration { - let secs = weeks.checked_mul(&SECS_PER_WEEK).expect("Duration::weeks out of bounds"); + let secs = weeks.checked_mul(SECS_PER_WEEK).expect("Duration::weeks out of bounds"); Duration::seconds(secs) } @@ -78,7 +77,7 @@ impl Duration { /// Fails when the duration is out of bounds. #[inline] pub fn days(days: i64) -> Duration { - let secs = days.checked_mul(&SECS_PER_DAY).expect("Duration::days out of bounds"); + let secs = days.checked_mul(SECS_PER_DAY).expect("Duration::days out of bounds"); Duration::seconds(secs) } @@ -87,7 +86,7 @@ impl Duration { /// Fails when the duration is out of bounds. #[inline] pub fn hours(hours: i64) -> Duration { - let secs = hours.checked_mul(&SECS_PER_HOUR).expect("Duration::hours ouf of bounds"); + let secs = hours.checked_mul(SECS_PER_HOUR).expect("Duration::hours ouf of bounds"); Duration::seconds(secs) } @@ -96,7 +95,7 @@ impl Duration { /// Fails when the duration is out of bounds. #[inline] pub fn minutes(minutes: i64) -> Duration { - let secs = minutes.checked_mul(&SECS_PER_MINUTE).expect("Duration::minutes out of bounds"); + let secs = minutes.checked_mul(SECS_PER_MINUTE).expect("Duration::minutes out of bounds"); Duration::seconds(secs) } @@ -191,33 +190,64 @@ impl Duration { /// Returns the total number of whole microseconds in the duration, /// or `None` on overflow (exceeding 2^63 microseconds in either direction). pub fn num_microseconds(&self) -> Option { - let secs_part = try_opt!(self.num_seconds().checked_mul(&MICROS_PER_SEC)); + let secs_part = try_opt!(self.num_seconds().checked_mul(MICROS_PER_SEC)); let nanos_part = self.nanos_mod_sec() / NANOS_PER_MICRO; - secs_part.checked_add(&(nanos_part as i64)) + secs_part.checked_add(nanos_part as i64) } /// Returns the total number of whole nanoseconds in the duration, /// or `None` on overflow (exceeding 2^63 nanoseconds in either direction). pub fn num_nanoseconds(&self) -> Option { - let secs_part = try_opt!(self.num_seconds().checked_mul(&(NANOS_PER_SEC as i64))); + let secs_part = try_opt!(self.num_seconds().checked_mul(NANOS_PER_SEC as i64)); let nanos_part = self.nanos_mod_sec(); - secs_part.checked_add(&(nanos_part as i64)) + secs_part.checked_add(nanos_part as i64) } -} -impl num::Bounded for Duration { - #[inline] fn min_value() -> Duration { MIN } - #[inline] fn max_value() -> Duration { MAX } -} + /// Add two durations, returning `None` if overflow occured. + pub fn checked_add(&self, rhs: &Duration) -> Option { + let mut secs = try_opt!(self.secs.checked_add(rhs.secs)); + let mut nanos = self.nanos + rhs.nanos; + if nanos >= NANOS_PER_SEC { + nanos -= NANOS_PER_SEC; + secs = try_opt!(secs.checked_add(1)); + } + let d = Duration { secs: secs, nanos: nanos }; + // Even if d is within the bounds of i64 seconds, + // it might still overflow i64 milliseconds. + if d < MIN || d > MAX { None } else { Some(d) } + } + + /// Subtract two durations, returning `None` if overflow occured. + pub fn checked_sub(&self, rhs: &Duration) -> Option { + let mut secs = try_opt!(self.secs.checked_sub(rhs.secs)); + let mut nanos = self.nanos - rhs.nanos; + if nanos < 0 { + nanos += NANOS_PER_SEC; + secs = try_opt!(secs.checked_sub(1)); + } + let d = Duration { secs: secs, nanos: nanos }; + // Even if d is within the bounds of i64 seconds, + // it might still overflow i64 milliseconds. + if d < MIN || d > MAX { None } else { Some(d) } + } -impl num::Zero for Duration { + /// The minimum possible `Duration`: `i64::MIN` milliseconds. #[inline] - fn zero() -> Duration { + pub fn min_value() -> Duration { MIN } + + /// The maximum possible `Duration`: `i64::MAX` milliseconds. + #[inline] + pub fn max_value() -> Duration { MAX } + + /// A duration where the stored seconds and nanoseconds are equal to zero. + #[inline] + pub fn zero() -> Duration { Duration { secs: 0, nanos: 0 } } + /// Returns `true` if the duration equals `Duration::zero()`. #[inline] - fn is_zero(&self) -> bool { + pub fn is_zero(&self) -> bool { self.secs == 0 && self.nanos == 0 } } @@ -245,21 +275,6 @@ impl Add for Duration { } } -impl num::CheckedAdd for Duration { - fn checked_add(&self, rhs: &Duration) -> Option { - let mut secs = try_opt!(self.secs.checked_add(&rhs.secs)); - let mut nanos = self.nanos + rhs.nanos; - if nanos >= NANOS_PER_SEC { - nanos -= NANOS_PER_SEC; - secs = try_opt!(secs.checked_add(&1)); - } - let d = Duration { secs: secs, nanos: nanos }; - // Even if d is within the bounds of i64 seconds, - // it might still overflow i64 milliseconds. - if d < MIN || d > MAX { None } else { Some(d) } - } -} - impl Sub for Duration { fn sub(&self, rhs: &Duration) -> Duration { let mut secs = self.secs - rhs.secs; @@ -272,21 +287,6 @@ impl Sub for Duration { } } -impl num::CheckedSub for Duration { - fn checked_sub(&self, rhs: &Duration) -> Option { - let mut secs = try_opt!(self.secs.checked_sub(&rhs.secs)); - let mut nanos = self.nanos - rhs.nanos; - if nanos < 0 { - nanos += NANOS_PER_SEC; - secs = try_opt!(secs.checked_sub(&1)); - } - let d = Duration { secs: secs, nanos: nanos }; - // Even if d is within the bounds of i64 seconds, - // it might still overflow i64 milliseconds. - if d < MIN || d > MAX { None } else { Some(d) } - } -} - impl Mul for Duration { fn mul(&self, rhs: &i32) -> Duration { // Multiply nanoseconds as i64, because it cannot overflow that way. @@ -379,15 +379,12 @@ fn div_rem_64(this: i64, other: i64) -> (i64, i64) { mod tests { use super::{Duration, MIN, MAX}; use {i32, i64}; - use num::{Zero, CheckedAdd, CheckedSub}; use option::{Some, None}; use to_string::ToString; #[test] fn test_duration() { - let d: Duration = Zero::zero(); - assert_eq!(d, Zero::zero()); - assert!(Duration::seconds(1) != Zero::zero()); + assert!(Duration::seconds(1) != Duration::zero()); assert_eq!(Duration::seconds(1) + Duration::seconds(2), Duration::seconds(3)); assert_eq!(Duration::seconds(86399) + Duration::seconds(4), Duration::days(1) + Duration::seconds(3)); @@ -403,8 +400,7 @@ mod tests { #[test] fn test_duration_num_days() { - let d: Duration = Zero::zero(); - assert_eq!(d.num_days(), 0); + assert_eq!(Duration::zero().num_days(), 0); assert_eq!(Duration::days(1).num_days(), 1); assert_eq!(Duration::days(-1).num_days(), -1); assert_eq!(Duration::seconds(86399).num_days(), 0); @@ -417,8 +413,7 @@ mod tests { #[test] fn test_duration_num_seconds() { - let d: Duration = Zero::zero(); - assert_eq!(d.num_seconds(), 0); + assert_eq!(Duration::zero().num_seconds(), 0); assert_eq!(Duration::seconds(1).num_seconds(), 1); assert_eq!(Duration::seconds(-1).num_seconds(), -1); assert_eq!(Duration::milliseconds(999).num_seconds(), 0); @@ -429,8 +424,7 @@ mod tests { #[test] fn test_duration_num_milliseconds() { - let d: Duration = Zero::zero(); - assert_eq!(d.num_milliseconds(), 0); + assert_eq!(Duration::zero().num_milliseconds(), 0); assert_eq!(Duration::milliseconds(1).num_milliseconds(), 1); assert_eq!(Duration::milliseconds(-1).num_milliseconds(), -1); assert_eq!(Duration::microseconds(999).num_milliseconds(), 0); @@ -445,8 +439,7 @@ mod tests { #[test] fn test_duration_num_microseconds() { - let d: Duration = Zero::zero(); - assert_eq!(d.num_microseconds(), Some(0)); + assert_eq!(Duration::zero().num_microseconds(), Some(0)); assert_eq!(Duration::microseconds(1).num_microseconds(), Some(1)); assert_eq!(Duration::microseconds(-1).num_microseconds(), Some(-1)); assert_eq!(Duration::nanoseconds(999).num_microseconds(), Some(0)); @@ -470,8 +463,7 @@ mod tests { #[test] fn test_duration_num_nanoseconds() { - let d: Duration = Zero::zero(); - assert_eq!(d.num_nanoseconds(), Some(0)); + assert_eq!(Duration::zero().num_nanoseconds(), Some(0)); assert_eq!(Duration::nanoseconds(1).num_nanoseconds(), Some(1)); assert_eq!(Duration::nanoseconds(-1).num_nanoseconds(), Some(-1)); assert_eq!(Duration::nanoseconds(i64::MAX).num_nanoseconds(), Some(i64::MAX)); @@ -504,10 +496,9 @@ mod tests { #[test] fn test_duration_mul() { - let d: Duration = Zero::zero(); - assert_eq!(d * i32::MAX, d); - assert_eq!(d * i32::MIN, d); - assert_eq!(Duration::nanoseconds(1) * 0, Zero::zero()); + assert_eq!(Duration::zero() * i32::MAX, Duration::zero()); + assert_eq!(Duration::zero() * i32::MIN, Duration::zero()); + assert_eq!(Duration::nanoseconds(1) * 0, Duration::zero()); assert_eq!(Duration::nanoseconds(1) * 1, Duration::nanoseconds(1)); assert_eq!(Duration::nanoseconds(1) * 1_000_000_000, Duration::seconds(1)); assert_eq!(Duration::nanoseconds(1) * -1_000_000_000, -Duration::seconds(1)); @@ -522,9 +513,8 @@ mod tests { #[test] fn test_duration_div() { - let d: Duration = Zero::zero(); - assert_eq!(d / i32::MAX, d); - assert_eq!(d / i32::MIN, d); + assert_eq!(Duration::zero() / i32::MAX, Duration::zero()); + assert_eq!(Duration::zero() / i32::MIN, Duration::zero()); assert_eq!(Duration::nanoseconds(123_456_789) / 1, Duration::nanoseconds(123_456_789)); assert_eq!(Duration::nanoseconds(123_456_789) / -1, -Duration::nanoseconds(123_456_789)); assert_eq!(-Duration::nanoseconds(123_456_789) / -1, Duration::nanoseconds(123_456_789)); @@ -540,8 +530,7 @@ mod tests { #[test] fn test_duration_fmt() { - let d: Duration = Zero::zero(); - assert_eq!(d.to_string(), "PT0S".to_string()); + assert_eq!(Duration::zero().to_string(), "PT0S".to_string()); assert_eq!(Duration::days(42).to_string(), "P42D".to_string()); assert_eq!(Duration::days(-42).to_string(), "-P42D".to_string()); assert_eq!(Duration::seconds(42).to_string(), "PT42S".to_string()); diff --git a/src/libsync/mpmc_bounded_queue.rs b/src/libsync/mpmc_bounded_queue.rs index f75511ecbc2e4..4414f710b1564 100644 --- a/src/libsync/mpmc_bounded_queue.rs +++ b/src/libsync/mpmc_bounded_queue.rs @@ -34,7 +34,7 @@ use core::prelude::*; use alloc::arc::Arc; use collections::Vec; -use core::num::next_power_of_two; +use core::num::UnsignedInt; use core::cell::UnsafeCell; use atomic::{AtomicUint,Relaxed,Release,Acquire}; @@ -66,7 +66,7 @@ impl State { 2u } else { // use next power of 2 as capacity - next_power_of_two(capacity) + capacity.next_power_of_two() } } else { capacity diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 639adb450783f..bf5f7ff9ad32c 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -19,8 +19,8 @@ use parse::token; use ptr::P; use std::fmt; -use std::num::Zero; use std::fmt::Show; +use std::num::Int; use std::rc::Rc; use serialize::{Encodable, Decodable, Encoder, Decoder}; @@ -857,9 +857,9 @@ pub enum Sign { Plus } -impl Sign { +impl Sign { pub fn new(n: T) -> Sign { - if n < Zero::zero() { + if n < Int::zero() { Minus } else { Plus diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index 996708b217426..51738ece80f53 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -20,6 +20,7 @@ use ptr::P; use std::cell::{Cell, RefCell}; use std::io::File; use std::rc::Rc; +use std::num::Int; use std::str; use std::iter; @@ -63,7 +64,7 @@ impl ParseSess { pub fn reserve_node_ids(&self, count: ast::NodeId) -> ast::NodeId { let v = self.node_id.get(); - match v.checked_add(&count) { + match v.checked_add(count) { Some(next) => { self.node_id.set(next); } None => panic!("Input too large, ran out of node ids!") } diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 6873c015fd51c..aab7c1b217846 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -87,6 +87,7 @@ use std::collections::HashSet; use std::io::fs::PathExtensions; use std::mem::replace; use std::mem; +use std::num::Float; use std::rc::Rc; use std::iter; diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs index 4d6aefb2a178d..1178848339710 100644 --- a/src/libtest/lib.rs +++ b/src/libtest/lib.rs @@ -60,6 +60,7 @@ use std::io::fs::PathExtensions; use std::io::stdio::StdWriter; use std::io::{File, ChanReader, ChanWriter}; use std::io; +use std::num::{Float, FloatMath, Int}; use std::os; use std::string::String; use std::task::TaskBuilder; @@ -106,7 +107,6 @@ enum NamePadding { PadNone, PadOnLeft, PadOnRight } impl TestDesc { fn padded_name(&self, column_count: uint, align: NamePadding) -> String { - use std::num::Saturating; let mut name = String::from_str(self.name.as_slice()); let fill = column_count.saturating_sub(name.len()); let mut pad = " ".repeat(fill); diff --git a/src/libtest/stats.rs b/src/libtest/stats.rs index 8c184ccbe43a8..adf58dc875c43 100644 --- a/src/libtest/stats.rs +++ b/src/libtest/stats.rs @@ -16,8 +16,7 @@ use std::fmt::Show; use std::hash::Hash; use std::io; use std::mem; -use std::num::Zero; -use std::num; +use std::num::{Float, FloatMath}; fn local_cmp(x: T, y: T) -> Ordering { // arbitrarily decide that NaNs are larger than everything. @@ -145,7 +144,6 @@ pub struct Summary { } impl Summary { - /// Construct a new summary of a sample set. pub fn new(samples: &[T]) -> Summary { Summary { @@ -166,7 +164,6 @@ impl Summary { } impl<'a, T: FloatMath + FromPrimitive> Stats for &'a [T] { - // FIXME #11059 handle NaN, inf and overflow fn sum(self) -> T { let mut partials = vec![]; @@ -176,15 +173,15 @@ impl<'a, T: FloatMath + FromPrimitive> Stats for &'a [T] { // This inner loop applies `hi`/`lo` summation to each // partial so that the list of partial sums remains exact. for i in range(0, partials.len()) { - let mut y = partials[i]; - if num::abs(x) < num::abs(y) { + let mut y: T = partials[i]; + if x.abs() < y.abs() { mem::swap(&mut x, &mut y); } // Rounded `x+y` is stored in `hi` with round-off stored in // `lo`. Together `hi+lo` are exactly equal to `x+y`. let hi = x + y; let lo = y - (hi - x); - if !lo.is_zero() { + if lo != Float::zero() { partials[j] = lo; j += 1; } @@ -197,7 +194,7 @@ impl<'a, T: FloatMath + FromPrimitive> Stats for &'a [T] { partials.truncate(j+1); } } - let zero: T = Zero::zero(); + let zero: T = Float::zero(); partials.iter().fold(zero, |p, q| p + *q) } @@ -222,10 +219,10 @@ impl<'a, T: FloatMath + FromPrimitive> Stats for &'a [T] { fn var(self) -> T { if self.len() < 2 { - Zero::zero() + Float::zero() } else { let mean = self.mean(); - let mut v: T = Zero::zero(); + let mut v: T = Float::zero(); for s in self.iter() { let x = *s - mean; v = v + x*x; @@ -249,7 +246,7 @@ impl<'a, T: FloatMath + FromPrimitive> Stats for &'a [T] { fn median_abs_dev(self) -> T { let med = self.median(); - let abs_devs: Vec = self.iter().map(|&v| num::abs(med - v)).collect(); + let abs_devs: Vec = self.iter().map(|&v| (med - v).abs()).collect(); // This constant is derived by smarter statistics brains than me, but it is // consistent with how R and other packages treat the MAD. let number = FromPrimitive::from_f64(1.4826).unwrap(); @@ -294,7 +291,7 @@ fn percentile_of_sorted(sorted_samples: &[T], if sorted_samples.len() == 1 { return sorted_samples[0]; } - let zero: T = Zero::zero(); + let zero: T = Float::zero(); assert!(zero <= pct); let hundred = FromPrimitive::from_uint(100).unwrap(); assert!(pct <= hundred); @@ -370,14 +367,14 @@ pub fn write_boxplot( let himag = ten.powf(s.max.abs().log10().floor()); // need to consider when the limit is zero - let zero: T = Zero::zero(); - let lo = if lomag.is_zero() { + let zero: T = Float::zero(); + let lo = if lomag == Float::zero() { zero } else { (s.min / lomag).floor() * lomag }; - let hi = if himag.is_zero() { + let hi = if himag == Float::zero() { zero } else { (s.max / himag).ceil() * himag @@ -464,6 +461,7 @@ mod tests { macro_rules! assert_approx_eq( ($a:expr, $b:expr) => ({ + use std::num::Float; let (a, b) = (&$a, &$b); assert!((*a - *b).abs() < 1.0e-6, "{} is not approximately equal to {}", *a, *b); diff --git a/src/libtime/lib.rs b/src/libtime/lib.rs index bbe6002717c8f..03b5186eef73a 100644 --- a/src/libtime/lib.rs +++ b/src/libtime/lib.rs @@ -30,7 +30,7 @@ extern crate libc; use std::fmt::Show; use std::fmt; use std::io::BufReader; -use std::num; +use std::num::SignedInt; use std::string::String; use std::time::Duration; @@ -757,7 +757,7 @@ impl<'a> fmt::Show for TmFmt<'a> { 'Z' => if tm.tm_gmtoff == 0_i32 { "GMT"} else { "" }, // FIXME (#2350): support locale 'z' => { let sign = if tm.tm_gmtoff > 0_i32 { '+' } else { '-' }; - let mut m = num::abs(tm.tm_gmtoff) / 60_i32; + let mut m = tm.tm_gmtoff.abs() / 60_i32; let h = m / 60_i32; m -= h * 60_i32; return write!(fmt, "{}{:02d}{:02d}", sign, h, m); @@ -799,7 +799,7 @@ impl<'a> fmt::Show for TmFmt<'a> { format: FmtStr("%Y-%m-%dT%H:%M:%S"), }; let sign = if self.tm.tm_gmtoff > 0_i32 { '+' } else { '-' }; - let mut m = num::abs(self.tm.tm_gmtoff) / 60_i32; + let mut m = self.tm.tm_gmtoff.abs() / 60_i32; let h = m / 60_i32; m -= h * 60_i32; write!(fmt, "{}{}{:02d}:{:02d}", s, sign, h as int, m as int) diff --git a/src/test/bench/noise.rs b/src/test/bench/noise.rs index 19ccf1b6caf72..4ad77a695dd5c 100644 --- a/src/test/bench/noise.rs +++ b/src/test/bench/noise.rs @@ -13,6 +13,7 @@ // ignore-lexer-test FIXME #15679 use std::f32::consts::PI; +use std::num::{Float, FloatMath}; use std::rand::{Rng, StdRng}; struct Vec2 { diff --git a/src/test/bench/shootout-fasta.rs b/src/test/bench/shootout-fasta.rs index e61ed47450423..f9fafa977acab 100644 --- a/src/test/bench/shootout-fasta.rs +++ b/src/test/bench/shootout-fasta.rs @@ -43,6 +43,7 @@ use std::io; use std::io::{BufferedWriter, File}; use std::cmp::min; +use std::num::Float; use std::os; const LINE_LENGTH: uint = 60; diff --git a/src/test/bench/shootout-k-nucleotide-pipes.rs b/src/test/bench/shootout-k-nucleotide-pipes.rs index b1cc52791ab88..e40c477ec66ef 100644 --- a/src/test/bench/shootout-k-nucleotide-pipes.rs +++ b/src/test/bench/shootout-k-nucleotide-pipes.rs @@ -19,6 +19,7 @@ extern crate collections; use std::collections::HashMap; use std::mem::replace; +use std::num::Float; use std::option; use std::os; use std::string::String; diff --git a/src/test/bench/shootout-nbody.rs b/src/test/bench/shootout-nbody.rs index 8486fa5b034d6..3bcc0c25df8ac 100644 --- a/src/test/bench/shootout-nbody.rs +++ b/src/test/bench/shootout-nbody.rs @@ -38,6 +38,8 @@ // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED // OF THE POSSIBILITY OF SUCH DAMAGE. +use std::num::Float; + const PI: f64 = 3.141592653589793; const SOLAR_MASS: f64 = 4.0 * PI * PI; const YEAR: f64 = 365.24; diff --git a/src/test/bench/shootout-spectralnorm.rs b/src/test/bench/shootout-spectralnorm.rs index 627742852b263..c5f2fbb189017 100644 --- a/src/test/bench/shootout-spectralnorm.rs +++ b/src/test/bench/shootout-spectralnorm.rs @@ -45,6 +45,7 @@ use std::iter::AdditiveIterator; use std::mem; +use std::num::Float; use std::os; use std::raw::Repr; use std::simd::f64x2; diff --git a/src/test/bench/sudoku.rs b/src/test/bench/sudoku.rs index 54824d7259fa9..6664eeecd5d85 100644 --- a/src/test/bench/sudoku.rs +++ b/src/test/bench/sudoku.rs @@ -15,6 +15,7 @@ use std::io; use std::io::stdio::StdReader; use std::io::BufferedReader; +use std::num::Int; use std::os; // Computes a single solution to a given 9x9 sudoku diff --git a/src/test/compile-fail/implicit-method-bind.rs b/src/test/compile-fail/implicit-method-bind.rs index 06a4088617a2b..34367f06793fc 100644 --- a/src/test/compile-fail/implicit-method-bind.rs +++ b/src/test/compile-fail/implicit-method-bind.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use std::num::SignedInt; + fn main() { let _f = 10i.abs; //~ ERROR attempted to take value of method } diff --git a/src/test/compile-fail/type-params-in-different-spaces-1.rs b/src/test/compile-fail/type-params-in-different-spaces-1.rs index c87e85417582d..66479202e1253 100644 --- a/src/test/compile-fail/type-params-in-different-spaces-1.rs +++ b/src/test/compile-fail/type-params-in-different-spaces-1.rs @@ -8,15 +8,15 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use std::num::Num; +use std::num::Int; -trait BrokenAdd: Num { +trait BrokenAdd: Int { fn broken_add(&self, rhs: T) -> Self { *self + rhs //~ ERROR expected `Self`, found `T` } } -impl BrokenAdd for T {} +impl BrokenAdd for T {} pub fn main() { let foo: u8 = 0u8; diff --git a/src/test/run-pass/const-binops.rs b/src/test/run-pass/const-binops.rs index c14f430e70983..f4dba3f6c7f5b 100644 --- a/src/test/run-pass/const-binops.rs +++ b/src/test/run-pass/const-binops.rs @@ -12,6 +12,7 @@ macro_rules! assert_approx_eq( ($a:expr, $b:expr) => ({ + use std::num::Float; let (a, b) = (&$a, &$b); assert!((*a - *b).abs() < 1.0e-6, "{} is not approximately equal to {}", *a, *b); diff --git a/src/test/run-pass/generic-extern-mangle.rs b/src/test/run-pass/generic-extern-mangle.rs index 69846750afc0f..6e3d19b05d4b1 100644 --- a/src/test/run-pass/generic-extern-mangle.rs +++ b/src/test/run-pass/generic-extern-mangle.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use std::num::Int; + extern "C" fn foo(a: T, b: T) -> T { a + b } fn main() { diff --git a/src/test/run-pass/intrinsics-math.rs b/src/test/run-pass/intrinsics-math.rs index 164a6845a9f0b..c3ba7ca12d02e 100644 --- a/src/test/run-pass/intrinsics-math.rs +++ b/src/test/run-pass/intrinsics-math.rs @@ -13,6 +13,7 @@ macro_rules! assert_approx_eq( ($a:expr, $b:expr) => ({ + use std::num::Float; let (a, b) = (&$a, &$b); assert!((*a - *b).abs() < 1.0e-6, "{} is not approximately equal to {}", *a, *b); diff --git a/src/test/run-pass/issue-11736.rs b/src/test/run-pass/issue-11736.rs index cdd3252df4bdc..912a62b5b0f6a 100644 --- a/src/test/run-pass/issue-11736.rs +++ b/src/test/run-pass/issue-11736.rs @@ -11,6 +11,7 @@ extern crate collections; use std::collections::Bitv; +use std::num::Float; fn main() { // Generate sieve of Eratosthenes for n up to 1e6 diff --git a/src/test/run-pass/trait-inheritance-num.rs b/src/test/run-pass/trait-inheritance-num.rs index 3b61a85995f63..e606018feb9c3 100644 --- a/src/test/run-pass/trait-inheritance-num.rs +++ b/src/test/run-pass/trait-inheritance-num.rs @@ -12,11 +12,11 @@ use std::cmp::{PartialEq, PartialOrd}; use std::num::NumCast; -pub trait NumExt: Num + NumCast + PartialEq + PartialOrd {} +pub trait NumExt: NumCast + PartialEq + PartialOrd {} pub trait FloatExt: NumExt {} -fn greater_than_one(n: &T) -> bool { *n > NumCast::from(1i).unwrap() } -fn greater_than_one_float(n: &T) -> bool { *n > NumCast::from(1i).unwrap() } +fn greater_than_one(n: &T) -> bool { *n > NumCast::from(1i).unwrap() } +fn greater_than_one_float(n: &T) -> bool { *n > NumCast::from(1i).unwrap() } pub fn main() {} diff --git a/src/test/run-pass/trait-inheritance-num0.rs b/src/test/run-pass/trait-inheritance-num0.rs index 16e702bb79aa4..42eaaa09fcdcc 100644 --- a/src/test/run-pass/trait-inheritance-num0.rs +++ b/src/test/run-pass/trait-inheritance-num0.rs @@ -11,6 +11,7 @@ // Extending Num and using inherited static methods +use std::cmp::PartialOrd; use std::num::NumCast; pub trait Num { @@ -18,7 +19,7 @@ pub trait Num { fn gt(&self, other: &Self) -> bool; } -pub trait NumExt: Num + NumCast { } +pub trait NumExt: NumCast + PartialOrd { } fn greater_than_one(n: &T) -> bool { n.gt(&NumCast::from(1i).unwrap()) diff --git a/src/test/run-pass/trait-inheritance-num1.rs b/src/test/run-pass/trait-inheritance-num1.rs index 5a2e88631a6e7..9407afbdd6b9c 100644 --- a/src/test/run-pass/trait-inheritance-num1.rs +++ b/src/test/run-pass/trait-inheritance-num1.rs @@ -11,7 +11,7 @@ use std::cmp::PartialOrd; use std::num::NumCast; -pub trait NumExt: Num + NumCast + PartialOrd { } +pub trait NumExt: NumCast + PartialOrd { } fn greater_than_one(n: &T) -> bool { *n > NumCast::from(1i).unwrap() diff --git a/src/test/run-pass/trait-inheritance-num2.rs b/src/test/run-pass/trait-inheritance-num2.rs index b3f769798b32a..1e6e7227a067c 100644 --- a/src/test/run-pass/trait-inheritance-num2.rs +++ b/src/test/run-pass/trait-inheritance-num2.rs @@ -12,6 +12,7 @@ // A more complex example of numeric extensions use std::cmp::{PartialEq, PartialOrd}; +use std::num::NumCast; pub trait TypeExt {} @@ -32,7 +33,7 @@ impl TypeExt for f32 {} impl TypeExt for f64 {} -pub trait NumExt: TypeExt + PartialEq + PartialOrd + Num + NumCast {} +pub trait NumExt: TypeExt + PartialEq + PartialOrd + NumCast {} impl NumExt for u8 {} impl NumExt for u16 {} diff --git a/src/test/run-pass/trait-inheritance-num3.rs b/src/test/run-pass/trait-inheritance-num3.rs index 415d0a04c8b9c..bd93223093ad2 100644 --- a/src/test/run-pass/trait-inheritance-num3.rs +++ b/src/test/run-pass/trait-inheritance-num3.rs @@ -11,11 +11,11 @@ use std::cmp::{PartialEq, PartialOrd}; use std::num::NumCast; -pub trait NumExt: PartialEq + PartialOrd + Num + NumCast {} +pub trait NumExt: PartialEq + PartialOrd + NumCast {} impl NumExt for f32 {} -fn num_eq_one(n: T) { +fn num_eq_one(n: T) { println!("{}", n == NumCast::from(1i).unwrap()) } diff --git a/src/test/run-pass/trait-inheritance-num5.rs b/src/test/run-pass/trait-inheritance-num5.rs index e3d631013c0fb..4c79600e2e9ba 100644 --- a/src/test/run-pass/trait-inheritance-num5.rs +++ b/src/test/run-pass/trait-inheritance-num5.rs @@ -11,7 +11,7 @@ use std::cmp::PartialEq; use std::num::NumCast; -pub trait NumExt: PartialEq + Num + NumCast {} +pub trait NumExt: PartialEq + NumCast {} impl NumExt for f32 {} impl NumExt for int {} diff --git a/src/test/run-pass/trait-inheritance-self-in-supertype.rs b/src/test/run-pass/trait-inheritance-self-in-supertype.rs index 63ac921e2a52b..96f1c940dcf2c 100644 --- a/src/test/run-pass/trait-inheritance-self-in-supertype.rs +++ b/src/test/run-pass/trait-inheritance-self-in-supertype.rs @@ -10,7 +10,7 @@ // Test for issue #4183: use of Self in supertraits. -use std::num; +use std::num::Float as StdFloat; pub static FUZZY_EPSILON: f64 = 0.1; @@ -29,7 +29,7 @@ impl FuzzyEq for f32 { } fn fuzzy_eq_eps(&self, other: &f32, epsilon: &f32) -> bool { - num::abs(*self - *other) < *epsilon + (*self - *other).abs() < *epsilon } } @@ -43,7 +43,7 @@ impl FuzzyEq for f64 { } fn fuzzy_eq_eps(&self, other: &f64, epsilon: &f64) -> bool { - num::abs(*self - *other) < *epsilon + (*self - *other).abs() < *epsilon } } diff --git a/src/test/run-pass/utf8_idents.rs b/src/test/run-pass/utf8_idents.rs index f6c4776a11cc8..c99c394969cf3 100644 --- a/src/test/run-pass/utf8_idents.rs +++ b/src/test/run-pass/utf8_idents.rs @@ -10,16 +10,15 @@ // // ignore-lexer-test FIXME #15679 - #![feature(non_ascii_idents)] -use std::num; +use std::num::Float; pub fn main() { let ε = 0.00001f64; let Π = 3.14f64; let लंच = Π * Π + 1.54; - assert!(num::abs((लंच - 1.54) - (Π * Π)) < ε); + assert!(((लंच - 1.54) - (Π * Π)).abs() < ε); assert_eq!(საჭმელად_გემრიელი_სადილი(), 0); }