Skip to content

Commit

Permalink
iterator: add a range_inclusive function
Browse files Browse the repository at this point in the history
Closes #6242
  • Loading branch information
thestinger committed Aug 21, 2013
1 parent 2bc999a commit 0d72f60
Showing 1 changed file with 52 additions and 0 deletions.
52 changes: 52 additions & 0 deletions src/libstd/iterator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1522,6 +1522,52 @@ impl<A: Sub<A, A> + Integer + Ord + Clone> DoubleEndedIterator<A> for Range<A> {
}
}

/// A range of numbers from [0, N]
#[deriving(Clone, DeepClone)]
pub struct RangeInclusive<A> {
priv range: Range<A>,
priv done: bool
}

/// Return an iterator over the range [start, stop]
#[inline]
pub fn range_inclusive<A: Add<A, A> + Ord + Clone + One>(start: A, stop: A) -> RangeInclusive<A> {
RangeInclusive{range: range(start, stop), done: false}
}

impl<A: Add<A, A> + Ord + Clone> Iterator<A> for RangeInclusive<A> {
#[inline]
fn next(&mut self) -> Option<A> {
match self.range.next() {
Some(x) => Some(x),
None => {
if self.done {
None
} else {
self.done = true;
Some(self.range.stop.clone())
}
}
}
}
}

impl<A: Sub<A, A> + Integer + Ord + Clone> DoubleEndedIterator<A> for RangeInclusive<A> {
#[inline]
fn next_back(&mut self) -> Option<A> {
if self.range.stop > self.range.state {
let result = self.range.stop.clone();
self.range.stop = self.range.stop - self.range.one;
Some(result)
} else if self.done {
None
} else {
self.done = true;
Some(self.range.stop.clone())
}
}
}

impl<A: Add<A, A> + Clone> Iterator<A> for Counter<A> {
#[inline]
fn next(&mut self) -> Option<A> {
Expand Down Expand Up @@ -2286,4 +2332,10 @@ mod tests {
fail!("unreachable");
}
}

#[test]
fn test_range_inclusive() {
assert_eq!(range_inclusive(0i, 5).collect::<~[int]>(), ~[0i, 1, 2, 3, 4, 5]);
assert_eq!(range_inclusive(0i, 5).invert().collect::<~[int]>(), ~[5i, 4, 3, 2, 1, 0]);
}
}

0 comments on commit 0d72f60

Please sign in to comment.