about summary refs log tree commit diff
diff options
context:
space:
mode:
authorDaniel Micay <danielmicay@gmail.com>2013-08-17 18:41:53 -0400
committerDaniel Micay <danielmicay@gmail.com>2013-08-20 22:05:03 -0400
commit0d72f604b7da4f03e7b30466af6b8b55f16c207b (patch)
treefe7fa56b76da85f04b5e82956126352a074906a9
parent2bc999a63693e668b2d0da311bc5aa74cd73da3e (diff)
downloadrust-0d72f604b7da4f03e7b30466af6b8b55f16c207b.tar.gz
rust-0d72f604b7da4f03e7b30466af6b8b55f16c207b.zip
iterator: add a `range_inclusive` function
Closes #6242
-rw-r--r--src/libstd/iterator.rs52
1 files changed, 52 insertions, 0 deletions
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<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> {
@@ -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]);
+    }
 }