Skip to content

Commit

Permalink
Auto merge of #23347 - aturon:stab-misc, r=alexcrichton
Browse files Browse the repository at this point in the history
This commit deprecates the `count`, `range` and `range_step` functions
in `iter`, in favor of range notation. To recover all existing
functionality, a new `step_by` adapter is provided directly on `ops::Range`
and `ops::RangeFrom`.

[breaking-change]

r? @alexcrichton
  • Loading branch information
bors committed Mar 16, 2015
2 parents cc78919 + 1d5983a commit bde09ee
Show file tree
Hide file tree
Showing 16 changed files with 134 additions and 93 deletions.
1 change: 1 addition & 0 deletions src/libcollections/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
#![feature(unsafe_destructor)]
#![feature(unique)]
#![feature(unsafe_no_drop_flag)]
#![feature(step_by)]
#![cfg_attr(test, feature(rand, rustc_private, test))]
#![cfg_attr(test, allow(deprecated))] // rand

Expand Down
6 changes: 3 additions & 3 deletions src/libcollections/slice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ use core::clone::Clone;
use core::cmp::Ordering::{self, Greater, Less};
use core::cmp::{self, Ord, PartialEq};
use core::iter::{Iterator, IteratorExt};
use core::iter::{range_step, MultiplicativeIterator};
use core::iter::MultiplicativeIterator;
use core::marker::Sized;
use core::mem::size_of;
use core::mem;
Expand Down Expand Up @@ -1387,7 +1387,7 @@ fn merge_sort<T, F>(v: &mut [T], mut compare: F) where F: FnMut(&T, &T) -> Order
// We could hardcode the sorting comparisons here, and we could
// manipulate/step the pointers themselves, rather than repeatedly
// .offset-ing.
for start in range_step(0, len, insertion) {
for start in (0.. len).step_by(insertion) {
// start <= i < len;
for i in start..cmp::min(start + insertion, len) {
// j satisfies: start <= j <= i;
Expand Down Expand Up @@ -1427,7 +1427,7 @@ fn merge_sort<T, F>(v: &mut [T], mut compare: F) where F: FnMut(&T, &T) -> Order
// a time, placing the result in `buf_tmp`.

// 0 <= start <= len.
for start in range_step(0, len, 2 * width) {
for start in (0..len).step_by(2 * width) {
// manipulate pointers directly for speed (rather than
// using a `for` loop with `range` and `.offset` inside
// that loop).
Expand Down
182 changes: 113 additions & 69 deletions src/libcore/iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ use default::Default;
use marker;
use mem;
use num::{ToPrimitive, Int};
use ops::{Add, Deref, FnMut};
use ops::{Add, Deref, FnMut, RangeFrom};
use option::Option;
use option::Option::{Some, None};
use marker::Sized;
Expand Down Expand Up @@ -2366,34 +2366,101 @@ impl<A, St, F> Iterator for Unfold<St, F> where F: FnMut(&mut St) -> Option<A> {
}
}

/// An adapter for stepping range iterators by a custom amount.
///
/// The resulting iterator handles overflow by stopping. The `A`
/// parameter is the type being iterated over, while `R` is the range
/// type (usually one of `std::ops::{Range, RangeFrom}`.
#[derive(Clone)]
#[unstable(feature = "step_by", reason = "recent addition")]
pub struct StepBy<A, R> {
step_by: A,
range: R,
}

impl<A: Add> RangeFrom<A> {
/// Creates an iterator starting at the same point, but stepping by
/// the given amount at each iteration.
///
/// # Examples
///
/// ```ignore
/// for i in (0u8..).step_by(2) {
/// println!("{}", i);
/// }
/// ```
///
/// This prints all even `u8` values.
#[unstable(feature = "step_by", reason = "recent addition")]
pub fn step_by(self, by: A) -> StepBy<A, Self> {
StepBy {
step_by: by,
range: self
}
}
}

impl<A: Int> ::ops::Range<A> {
/// Creates an iterator with the same range, but stepping by the
/// given amount at each iteration.
///
/// The resulting iterator handles overflow by stopping.
///
/// # Examples
///
/// ```
/// # #![feature(step_by, core)]
/// for i in (0..10).step_by(2) {
/// println!("{}", i);
/// }
/// ```
///
/// This prints:
///
/// ```text
/// 0
/// 2
/// 4
/// 6
/// 8
/// ```
#[unstable(feature = "step_by", reason = "recent addition")]
pub fn step_by(self, by: A) -> StepBy<A, Self> {
StepBy {
step_by: by,
range: self
}
}
}

/// An infinite iterator starting at `start` and advancing by `step` with each
/// iteration
#[derive(Clone)]
#[unstable(feature = "core",
reason = "may be renamed or replaced by range notation adapters")]
pub struct Counter<A> {
/// The current state the counter is at (next value to be yielded)
state: A,
/// The amount that this iterator is stepping by
step: A,
}
#[deprecated(since = "1.0.0-beta", reason = "use range notation and step_by")]
pub type Counter<A> = StepBy<A, RangeFrom<A>>;

/// Creates a new counter with the specified start/step
/// Deprecated: use `(start..).step_by(step)` instead.
#[inline]
#[unstable(feature = "core",
reason = "may be renamed or replaced by range notation adapters")]
#[deprecated(since = "1.0.0-beta", reason = "use (start..).step_by(step) instead")]
#[allow(deprecated)]
pub fn count<A>(start: A, step: A) -> Counter<A> {
Counter{state: start, step: step}
StepBy {
range: RangeFrom { start: start },
step_by: step,
}
}

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

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

Expand All @@ -2404,31 +2471,22 @@ impl<A: Add<Output=A> + Clone> Iterator for Counter<A> {
}

/// An iterator over the range [start, stop)
#[allow(deprecated)]
#[derive(Clone)]
#[unstable(feature = "core",
reason = "will be replaced by range notation")]
#[deprecated(since = "1.0.0-beta", reason = "use range notation")]
pub struct Range<A> {
state: A,
stop: A,
one: A,
}

/// Returns an iterator over the given range [start, stop) (that is, starting
/// at start (inclusive), and ending at stop (exclusive)).
///
/// # Examples
///
/// ```
/// let array = [0, 1, 2, 3, 4];
///
/// for i in range(0, 5) {
/// println!("{}", i);
/// assert_eq!(i, array[i]);
/// }
/// ```
/// Deprecated: use `(start..stop)` instead.
#[inline]
#[unstable(feature = "core",
reason = "will be replaced by range notation")]
#[unstable(feature = "core", reason = "will be replaced by range notation")]
#[deprecated(since = "1.0.0-beta", reason = "use (start..stop) instead")]
#[allow(deprecated)]
pub fn range<A: Int>(start: A, stop: A) -> Range<A> {
Range {
state: start,
Expand All @@ -2440,6 +2498,8 @@ pub fn range<A: Int>(start: A, stop: A) -> Range<A> {
// FIXME: #10414: Unfortunate type bound
#[unstable(feature = "core",
reason = "will be replaced by range notation")]
#[deprecated(since = "1.0.0-beta", reason = "use range notation")]
#[allow(deprecated)]
impl<A: Int + ToPrimitive> Iterator for Range<A> {
type Item = A;

Expand Down Expand Up @@ -2491,6 +2551,8 @@ impl<A: Int + ToPrimitive> Iterator for Range<A> {
/// the direction it is consumed.
#[unstable(feature = "core",
reason = "will be replaced by range notation")]
#[deprecated(since = "1.0.0-beta", reason = "use range notation")]
#[allow(deprecated)]
impl<A: Int + ToPrimitive> DoubleEndedIterator for Range<A> {
#[inline]
fn next_back(&mut self) -> Option<A> {
Expand All @@ -2507,6 +2569,7 @@ impl<A: Int + ToPrimitive> DoubleEndedIterator for Range<A> {
#[derive(Clone)]
#[unstable(feature = "core",
reason = "likely to be replaced by range notation and adapters")]
#[allow(deprecated)]
pub struct RangeInclusive<A> {
range: Range<A>,
done: bool,
Expand All @@ -2516,6 +2579,7 @@ pub struct RangeInclusive<A> {
#[inline]
#[unstable(feature = "core",
reason = "likely to be replaced by range notation and adapters")]
#[allow(deprecated)]
pub fn range_inclusive<A: Int>(start: A, stop: A) -> RangeInclusive<A> {
RangeInclusive {
range: range(start, stop),
Expand All @@ -2525,6 +2589,7 @@ pub fn range_inclusive<A: Int>(start: A, stop: A) -> RangeInclusive<A> {

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

Expand Down Expand Up @@ -2561,6 +2626,7 @@ impl<A: Int + ToPrimitive> Iterator for RangeInclusive<A> {

#[unstable(feature = "core",
reason = "likely to be replaced by range notation and adapters")]
#[allow(deprecated)]
impl<A: Int + ToPrimitive> DoubleEndedIterator for RangeInclusive<A> {
#[inline]
fn next_back(&mut self) -> Option<A> {
Expand All @@ -2578,61 +2644,39 @@ impl<A: Int + ToPrimitive> DoubleEndedIterator for RangeInclusive<A> {
}

/// An iterator over the range [start, stop) by `step`. It handles overflow by stopping.
#[derive(Clone)]
#[unstable(feature = "core",
reason = "likely to be replaced by range notation and adapters")]
pub struct RangeStep<A> {
state: A,
stop: A,
step: A,
rev: bool,
}
#[deprecated(since = "1.0.0-beta", reason = "use range notation and step_by")]
pub type RangeStep<A> = StepBy<A, ::ops::Range<A>>;

/// Return an iterator over the range [start, stop) by `step`.
///
/// It handles overflow by stopping.
///
/// # Examples
///
/// ```
/// use std::iter::range_step;
///
/// for i in range_step(0, 10, 2) {
/// println!("{}", i);
/// }
/// ```
///
/// This prints:
///
/// ```text
/// 0
/// 2
/// 4
/// 6
/// 8
/// ```
/// Deprecated: use `(start..stop).step_by(step)` instead.
#[inline]
#[unstable(feature = "core",
reason = "likely to be replaced by range notation and adapters")]
#[deprecated(since = "1.0.0-beta",
reason = "use `(start..stop).step_by(step)` instead")]
#[allow(deprecated)]
pub fn range_step<A: Int>(start: A, stop: A, step: A) -> RangeStep<A> {
let rev = step < Int::zero();
RangeStep{state: start, stop: stop, step: step, rev: rev}
StepBy {
step_by: step,
range: ::ops::Range { start: start, end: stop },
}
}

#[unstable(feature = "core",
reason = "likely to be replaced by range notation and adapters")]
impl<A: Int> Iterator for RangeStep<A> {
#[stable(feature = "rust1", since = "1.0.0")]
impl<A: Int> Iterator for StepBy<A, ::ops::Range<A>> {
type Item = A;

#[inline]
fn next(&mut self) -> Option<A> {
if (self.rev && self.state > self.stop) || (!self.rev && self.state < self.stop) {
let result = self.state;
match self.state.checked_add(self.step) {
Some(x) => self.state = x,
None => self.state = self.stop.clone()
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()
}
Some(result)
Some(start)
} else {
None
}
Expand Down
1 change: 1 addition & 0 deletions src/libcore/prelude.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ pub use marker::{Copy, Send, Sized, Sync};
pub use ops::{Drop, Fn, FnMut, FnOnce};

// Reexported functions
#[allow(deprecated)]
pub use iter::range;
pub use mem::drop;

Expand Down
12 changes: 6 additions & 6 deletions src/libcoretest/iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -775,12 +775,12 @@ fn test_range_inclusive() {

#[test]
fn test_range_step() {
assert_eq!(range_step(0, 20, 5).collect::<Vec<int>>(), [0, 5, 10, 15]);
assert_eq!(range_step(20, 0, -5).collect::<Vec<int>>(), [20, 15, 10, 5]);
assert_eq!(range_step(20, 0, -6).collect::<Vec<int>>(), [20, 14, 8, 2]);
assert_eq!(range_step(200, 255, 50).collect::<Vec<u8>>(), [200, 250]);
assert_eq!(range_step(200, -5, 1).collect::<Vec<int>>(), []);
assert_eq!(range_step(200, 200, 1).collect::<Vec<int>>(), []);
assert_eq!((0..20).step_by(5).collect::<Vec<int>>(), [0, 5, 10, 15]);
assert_eq!((20..0).step_by(-5).collect::<Vec<int>>(), [20, 15, 10, 5]);
assert_eq!((20..0).step_by(-6).collect::<Vec<int>>(), [20, 14, 8, 2]);
assert_eq!((200..255).step_by(50).collect::<Vec<u8>>(), [200, 250]);
assert_eq!((200..-5).step_by(1).collect::<Vec<int>>(), []);
assert_eq!((200..200).step_by(1).collect::<Vec<int>>(), []);
}

#[test]
Expand Down
2 changes: 0 additions & 2 deletions src/librand/distributions/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@
//! internally. The `IndependentSample` trait is for generating values
//! that do not need to record state.
#![unstable(feature = "rand")]

use core::prelude::*;
use core::num::{Float, Int};
use core::marker::PhantomData;
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/infer/combine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ pub trait Combine<'tcx> : Sized {
b_tys.len())));
}

range(0, a_tys.len()).map(|i| {
(0.. a_tys.len()).map(|i| {
let a_ty = a_tys[i];
let b_ty = b_tys[i];
let v = variances.map_or(ty::Invariant, |v| v[i]);
Expand Down
1 change: 1 addition & 0 deletions src/librustc_back/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
#![feature(path_ext)]
#![feature(std_misc)]
#![feature(path_relative_from)]
#![feature(step_by)]

extern crate syntax;
extern crate serialize;
Expand Down
3 changes: 1 addition & 2 deletions src/librustc_back/svh.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@
use std::fmt;
use std::hash::{Hash, SipHasher, Hasher};
use std::iter::range_step;
use syntax::ast;
use syntax::visit;

Expand Down Expand Up @@ -103,7 +102,7 @@ impl Svh {

let hash = state.finish();
return Svh {
hash: range_step(0, 64, 4).map(|i| hex(hash >> i)).collect()
hash: (0..64).step_by(4).map(|i| hex(hash >> i)).collect()
};

fn hex(b: u64) -> char {
Expand Down
Loading

0 comments on commit bde09ee

Please sign in to comment.