From 0d72f604b7da4f03e7b30466af6b8b55f16c207b Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Sat, 17 Aug 2013 18:41:53 -0400 Subject: [PATCH] iterator: add a `range_inclusive` function Closes #6242 --- src/libstd/iterator.rs | 52 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/src/libstd/iterator.rs b/src/libstd/iterator.rs index 1d32c5df14e..554913ab5ec 100644 --- a/src/libstd/iterator.rs +++ b/src/libstd/iterator.rs @@ -1522,6 +1522,52 @@ impl + Integer + Ord + Clone> DoubleEndedIterator for Range { } } +/// A range of numbers from [0, N] +#[deriving(Clone, DeepClone)] +pub struct RangeInclusive { + priv range: Range, + priv done: bool +} + +/// Return an iterator over the range [start, stop] +#[inline] +pub fn range_inclusive + Ord + Clone + One>(start: A, stop: A) -> RangeInclusive { + RangeInclusive{range: range(start, stop), done: false} +} + +impl + Ord + Clone> Iterator for RangeInclusive { + #[inline] + fn next(&mut self) -> Option { + match self.range.next() { + Some(x) => Some(x), + None => { + if self.done { + None + } else { + self.done = true; + Some(self.range.stop.clone()) + } + } + } + } +} + +impl + Integer + Ord + Clone> DoubleEndedIterator for RangeInclusive { + #[inline] + fn next_back(&mut self) -> Option { + 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 + Clone> Iterator for Counter { #[inline] fn next(&mut self) -> Option { @@ -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]); + } }