diff options
Diffstat (limited to 'src/libcore/iter.rs')
| -rw-r--r-- | src/libcore/iter.rs | 182 |
1 files changed, 113 insertions, 69 deletions
diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs index 237dbe492ba..8ebedb66851 100644 --- a/src/libcore/iter.rs +++ b/src/libcore/iter.rs @@ -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; @@ -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) } @@ -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, @@ -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; @@ -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> { @@ -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, @@ -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), @@ -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; @@ -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> { @@ -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 } |
