summary refs log tree commit diff
path: root/src/libstd/iterator.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/libstd/iterator.rs')
-rw-r--r--src/libstd/iterator.rs43
1 files changed, 36 insertions, 7 deletions
diff --git a/src/libstd/iterator.rs b/src/libstd/iterator.rs
index 1be398966bb..d10a5541e41 100644
--- a/src/libstd/iterator.rs
+++ b/src/libstd/iterator.rs
@@ -18,9 +18,9 @@ implementing the `Iterator` trait.
 */
 
 use cmp;
-use num::{Zero, One, Saturating};
+use num::{Zero, One, Integer, Saturating};
 use option::{Option, Some, None};
-use ops::{Add, Mul};
+use ops::{Add, Mul, Sub};
 use cmp::Ord;
 use clone::Clone;
 use uint;
@@ -674,7 +674,7 @@ impl<A, T: Iterator<A>> IteratorUtil<A> for T {
                     Some((y, y_val))
                 }
             }
-        }).map_consume(|(x, _)| x)
+        }).map_move(|(x, _)| x)
     }
 
     #[inline]
@@ -689,7 +689,7 @@ impl<A, T: Iterator<A>> IteratorUtil<A> for T {
                     Some((y, y_val))
                 }
             }
-        }).map_consume(|(x, _)| x)
+        }).map_move(|(x, _)| x)
     }
 }
 
@@ -1382,7 +1382,7 @@ impl<'self, A, T: Iterator<A>, B, U: Iterator<B>> Iterator<B> for
                     return Some(x)
                 }
             }
-            match self.iter.next().map_consume(|x| (self.f)(x)) {
+            match self.iter.next().map_move(|x| (self.f)(x)) {
                 None => return self.backiter.chain_mut_ref(|it| it.next()),
                 next => self.frontiter = next,
             }
@@ -1414,7 +1414,7 @@ impl<'self,
                     y => return y
                 }
             }
-            match self.iter.next_back().map_consume(|x| (self.f)(x)) {
+            match self.iter.next_back().map_move(|x| (self.f)(x)) {
                 None => return self.frontiter.chain_mut_ref(|it| it.next_back()),
                 next => self.backiter = next,
             }
@@ -1531,7 +1531,7 @@ pub fn range<A: Add<A, A> + Ord + Clone + One>(start: A, stop: A) -> Range<A> {
     Range{state: start, stop: stop, one: One::one()}
 }
 
-impl<A: Add<A, A> + Ord + Clone + One> Iterator<A> for Range<A> {
+impl<A: Add<A, A> + Ord + Clone> Iterator<A> for Range<A> {
     #[inline]
     fn next(&mut self) -> Option<A> {
         if self.state < self.stop {
@@ -1544,6 +1544,22 @@ impl<A: Add<A, A> + Ord + Clone + One> Iterator<A> for Range<A> {
     }
 }
 
+impl<A: Sub<A, A> + Integer + Ord + Clone> DoubleEndedIterator<A> for Range<A> {
+    #[inline]
+    fn next_back(&mut self) -> Option<A> {
+        if self.stop > self.state {
+            // Integer doesn't technically define this rule, but we're going to assume that every
+            // Integer is reachable from every other one by adding or subtracting enough Ones. This
+            // seems like a reasonable-enough rule that every Integer should conform to, even if it
+            // can't be statically checked.
+            self.stop = self.stop - self.one;
+            Some(self.stop.clone())
+        } else {
+            None
+        }
+    }
+}
+
 impl<A: Add<A, A> + Clone> Iterator<A> for Counter<A> {
     #[inline]
     fn next(&mut self) -> Option<A> {
@@ -2121,4 +2137,17 @@ mod tests {
         check_randacc_iter(xs.iter().cycle().take_(27), 27);
         check_randacc_iter(empty.iter().cycle(), 0);
     }
+
+    #[test]
+    fn test_double_ended_range() {
+        assert_eq!(range(11i, 14).invert().collect::<~[int]>(), ~[13i, 12, 11]);
+        for _ in range(10i, 0).invert() {
+            fail!("unreachable");
+        }
+
+        assert_eq!(range(11u, 14).invert().collect::<~[uint]>(), ~[13u, 12, 11]);
+        for _ in range(10u, 0).invert() {
+            fail!("unreachable");
+        }
+    }
 }