Skip to content

Commit

Permalink
rollup merge of rust-lang#23549: aturon/stab-num
Browse files Browse the repository at this point in the history
This commit stabilizes the `std::num` module:

* The `Int` and `Float` traits are deprecated in favor of (1) the
  newly-added inherent methods and (2) the generic traits available in
  rust-lang/num.

* The `Zero` and `One` traits are reintroduced in `std::num`, which
  together with various other traits allow you to recover the most
  common forms of generic programming.

* The `FromStrRadix` trait, and associated free function, is deprecated
  in favor of inherent implementations.

* A wide range of methods and constants for both integers and floating
  point numbers are now `#[stable]`, having been adjusted for integer
  guidelines.

* `is_positive` and `is_negative` are renamed to `is_sign_positive` and
  `is_sign_negative`, in order to address rust-lang#22985

* The `Wrapping` type is moved to `std::num` and stabilized;
  `WrappingOps` is deprecated in favor of inherent methods on the
  integer types, and direct implementation of operations on
  `Wrapping<X>` for each concrete integer type `X`.

Closes rust-lang#22985
Closes rust-lang#21069

[breaking-change]

r? @alexcrichton
  • Loading branch information
alexcrichton committed Mar 31, 2015
2 parents b3317d6 + 232424d commit 5d0beb7
Show file tree
Hide file tree
Showing 48 changed files with 985 additions and 1,251 deletions.
1 change: 0 additions & 1 deletion src/liballoc/heap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,6 @@ mod imp {
use core::option::Option;
use core::option::Option::None;
use core::ptr::{null_mut, null};
use core::num::Int;
use libc::{c_char, c_int, c_void, size_t};
use super::MIN_ALIGN;

Expand Down
1 change: 0 additions & 1 deletion src/libcollections/bit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,6 @@ use core::hash;
use core::iter::RandomAccessIterator;
use core::iter::{Chain, Enumerate, Repeat, Skip, Take, repeat, Cloned};
use core::iter::{self, FromIterator, IntoIterator};
use core::num::Int;
use core::ops::Index;
use core::slice;
use core::{u8, u32, usize};
Expand Down
1 change: 0 additions & 1 deletion src/libcollections/enum_set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
use core::prelude::*;
use core::marker;
use core::fmt;
use core::num::Int;
use core::iter::{FromIterator, IntoIterator};
use core::ops::{Sub, BitOr, BitAnd, BitXor};

Expand Down
1 change: 1 addition & 0 deletions src/libcollections/slice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ use core::iter::MultiplicativeIterator;
use core::marker::Sized;
use core::mem::size_of;
use core::mem;
#[cfg(stage0)]
use core::num::wrapping::WrappingOps;
use core::ops::FnMut;
use core::option::Option::{self, Some, None};
Expand Down
3 changes: 0 additions & 3 deletions src/libcollections/str.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,6 @@
//! (see below). It is not possible to move out of borrowed strings because they
//! are owned elsewhere.
//!
//! Basic operations are implemented directly by the compiler, but more advanced
//! operations are defined as methods on the `str` type.
//!
//! # Examples
//!
//! Here's some code that uses a `&str`:
Expand Down
1 change: 1 addition & 0 deletions src/libcollections/vec_deque.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ use core::default::Default;
use core::fmt;
use core::iter::{self, repeat, FromIterator, IntoIterator, RandomAccessIterator};
use core::mem;
#[cfg(stage0)]
use core::num::wrapping::WrappingOps;
use core::ops::{Index, IndexMut};
use core::ptr::{self, Unique};
Expand Down
2 changes: 0 additions & 2 deletions src/libcore/cmp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@
//!
//! ```
//! # #![feature(core)]
//! use std::num::SignedInt;
//!
//! struct FuzzyNum {
//! num: i32,
//! }
Expand Down
1 change: 1 addition & 0 deletions src/libcore/fmt/num.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ trait GenericRadix {
fn digit(&self, x: u8) -> u8;

/// Format an integer using the radix using a formatter.
#[allow(deprecated)] // Int
fn fmt_int<T: 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.
Expand Down
5 changes: 3 additions & 2 deletions src/libcore/hash/sip.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,10 @@

//! An implementation of SipHash 2-4.

#![allow(deprecated)] // until the next snapshot for inherent wrapping ops

use prelude::*;
use default::Default;
use num::wrapping::WrappingOps;
use super::Hasher;

/// An implementation of SipHash 2-4.
Expand Down Expand Up @@ -71,7 +72,7 @@ macro_rules! u8to64_le {

macro_rules! rotl {
($x:expr, $b:expr) =>
(($x << $b) | ($x >> (64.wrapping_sub($b))))
(($x << $b) | ($x >> (64_i32.wrapping_sub($b))))
}

macro_rules! compress {
Expand Down
158 changes: 122 additions & 36 deletions src/libcore/iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,8 @@ use cmp::Ord;
use default::Default;
use marker;
use mem;
use num::{ToPrimitive, Int};
use ops::{Add, FnMut, RangeFrom};
use num::{Int, Zero, One, ToPrimitive};
use ops::{Add, Sub, FnMut, RangeFrom};
use option::Option;
use option::Option::{Some, None};
use marker::Sized;
Expand Down Expand Up @@ -843,9 +843,8 @@ pub trait Iterator {
///
/// ```
/// # #![feature(core)]
/// use std::num::SignedInt;
///
/// let a = [-3, 0, 1, 5, -10];
/// let a = [-3_i32, 0, 1, 5, -10];
/// assert_eq!(*a.iter().max_by(|x| x.abs()).unwrap(), -10);
/// ```
#[inline]
Expand Down Expand Up @@ -875,9 +874,8 @@ pub trait Iterator {
///
/// ```
/// # #![feature(core)]
/// use std::num::SignedInt;
///
/// let a = [-3, 0, 1, 5, -10];
/// let a = [-3_i32, 0, 1, 5, -10];
/// assert_eq!(*a.iter().min_by(|x| x.abs()).unwrap(), 0);
/// ```
#[inline]
Expand Down Expand Up @@ -2417,6 +2415,67 @@ impl<A, St, F> Iterator for Unfold<St, F> where F: FnMut(&mut St) -> Option<A> {
}
}

/// Objects that can be stepped over in both directions.
///
/// The `steps_between` function provides a way to efficiently compare
/// two `Step` objects.
#[unstable(feature = "step_trait",
reason = "likely to be replaced by finer-grained traits")]
pub trait Step: Ord {
/// Steps `self` if possible.
fn step(&self, by: &Self) -> Option<Self>;

/// The number of steps between two step objects.
///
/// `start` should always be less than `end`, so the result should never
/// be negative.
///
/// Return `None` if it is not possible to calculate steps_between
/// without overflow.
fn steps_between(start: &Self, end: &Self, by: &Self) -> Option<usize>;
}

macro_rules! step_impl {
($($t:ty)*) => ($(
impl Step for $t {
#[inline]
fn step(&self, by: &$t) -> Option<$t> {
(*self).checked_add(*by)
}
#[inline]
#[allow(trivial_numeric_casts)]
fn steps_between(start: &$t, end: &$t, by: &$t) -> Option<usize> {
if *start <= *end {
Some(((*end - *start) / *by) as usize)
} else {
Some(0)
}
}
}
)*)
}

macro_rules! step_impl_no_between {
($($t:ty)*) => ($(
impl Step for $t {
#[inline]
fn step(&self, by: &$t) -> Option<$t> {
(*self).checked_add(*by)
}
#[inline]
fn steps_between(_a: &$t, _b: &$t, _by: &$t) -> Option<usize> {
None
}
}
)*)
}

step_impl!(usize u8 u16 u32 isize i8 i16 i32);
#[cfg(target_pointer_width = "64")]
step_impl!(u64 i64);
#[cfg(target_pointer_width = "32")]
step_impl_no_between!(u64 i64);

/// An adapter for stepping range iterators by a custom amount.
///
/// The resulting iterator handles overflow by stopping. The `A`
Expand All @@ -2429,7 +2488,7 @@ pub struct StepBy<A, R> {
range: R,
}

impl<A: Add> RangeFrom<A> {
impl<A: Step> RangeFrom<A> {
/// Creates an iterator starting at the same point, but stepping by
/// the given amount at each iteration.
///
Expand All @@ -2451,7 +2510,8 @@ impl<A: Add> RangeFrom<A> {
}
}

impl<A: Int> ::ops::Range<A> {
#[allow(deprecated)]
impl<A: Step> ::ops::Range<A> {
/// Creates an iterator with the same range, but stepping by the
/// given amount at each iteration.
///
Expand Down Expand Up @@ -2505,14 +2565,17 @@ pub fn count<A>(start: A, step: A) -> Counter<A> {
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<A: Add<Output=A> + Clone> Iterator for StepBy<A, RangeFrom<A>> {
impl<A> Iterator for StepBy<A, RangeFrom<A>> where
A: Clone,
for<'a> &'a A: Add<&'a A, Output = A>
{
type Item = A;

#[inline]
fn next(&mut self) -> Option<A> {
let result = self.range.start.clone();
self.range.start = result.clone() + self.step_by.clone();
Some(result)
let mut n = &self.range.start + &self.step_by;
mem::swap(&mut n, &mut self.range.start);
Some(n)
}

#[inline]
Expand Down Expand Up @@ -2715,19 +2778,27 @@ pub fn range_step<A: Int>(start: A, stop: A, step: A) -> RangeStep<A> {
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<A: Int> Iterator for StepBy<A, ::ops::Range<A>> {
#[allow(deprecated)]
impl<A: Step + Zero + Clone> Iterator for StepBy<A, ::ops::Range<A>> {
type Item = A;

#[inline]
fn next(&mut self) -> Option<A> {
let rev = self.step_by < Int::zero();
let start = self.range.start;
if (rev && start > self.range.end) || (!rev && start < self.range.end) {
match start.checked_add(self.step_by) {
Some(x) => self.range.start = x,
None => self.range.start = self.range.end.clone()
let rev = self.step_by < A::zero();
if (rev && self.range.start > self.range.end) ||
(!rev && self.range.start < self.range.end)
{
match self.range.start.step(&self.step_by) {
Some(mut n) => {
mem::swap(&mut self.range.start, &mut n);
Some(n)
},
None => {
let mut n = self.range.end.clone();
mem::swap(&mut self.range.start, &mut n);
Some(n)
}
}
Some(start)
} else {
None
}
Expand Down Expand Up @@ -2774,6 +2845,7 @@ pub struct RangeStepInclusive<A> {
#[inline]
#[unstable(feature = "core",
reason = "likely to be replaced by range notation and adapters")]
#[allow(deprecated)]
pub fn range_step_inclusive<A: Int>(start: A, stop: A, step: A) -> RangeStepInclusive<A> {
let rev = step < Int::zero();
RangeStepInclusive {
Expand All @@ -2787,6 +2859,7 @@ pub fn range_step_inclusive<A: Int>(start: A, stop: A, step: A) -> RangeStepIncl

#[unstable(feature = "core",
reason = "likely to be replaced by range notation and adapters")]
#[allow(deprecated)]
impl<A: Int> Iterator for RangeStepInclusive<A> {
type Item = A;

Expand Down Expand Up @@ -2814,27 +2887,36 @@ macro_rules! range_exact_iter_impl {
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<A: Int> Iterator for ::ops::Range<A> {
#[allow(deprecated)]
impl<A: Step + One + Clone> Iterator for ::ops::Range<A> {
type Item = A;

#[inline]
fn next(&mut self) -> Option<A> {
if self.start < self.end {
let result = self.start;
self.start = self.start + Int::one();
Some(result)
match self.start.step(&A::one()) {
Some(mut n) => {
mem::swap(&mut n, &mut self.start);
Some(n)
},
None => {
let mut n = self.end.clone();
mem::swap(&mut n, &mut self.start);
Some(n)

}
}
} else {
None
}
}

#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
if self.start >= self.end {
(0, Some(0))
if let Some(hint) = Step::steps_between(&self.start, &self.end, &A::one()) {
(hint, Some(hint))
} else {
let length = (self.end - self.start).to_usize();
(length.unwrap_or(0), length)
(0, None)
}
}
}
Expand All @@ -2844,28 +2926,32 @@ impl<A: Int> Iterator for ::ops::Range<A> {
range_exact_iter_impl!(usize u8 u16 u32 isize i8 i16 i32);

#[stable(feature = "rust1", since = "1.0.0")]
impl<A: Int> DoubleEndedIterator for ::ops::Range<A> {
#[allow(deprecated)]
impl<A: Step + One + Clone> DoubleEndedIterator for ::ops::Range<A> where
for<'a> &'a A: Sub<&'a A, Output = A>
{
#[inline]
fn next_back(&mut self) -> Option<A> {
if self.start < self.end {
self.end = self.end - Int::one();
Some(self.end)
self.end = &self.end - &A::one();
Some(self.end.clone())
} else {
None
}
}
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<A: Int> Iterator for ::ops::RangeFrom<A> {
#[allow(deprecated)]
impl<A: Step + One> Iterator for ::ops::RangeFrom<A> {
type Item = A;

#[inline]
fn next(&mut self) -> Option<A> {
let result = self.start;
self.start = self.start + Int::one();
debug_assert!(result < self.start);
Some(result)
self.start.step(&A::one()).map(|mut n| {
mem::swap(&mut n, &mut self.start);
n
})
}
}

Expand Down
Loading

0 comments on commit 5d0beb7

Please sign in to comment.