about summary refs log tree commit diff
path: root/src/libcore/iter.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/libcore/iter.rs')
-rw-r--r--src/libcore/iter.rs104
1 files changed, 67 insertions, 37 deletions
diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs
index 0005db36c27..faf8ccbc90e 100644
--- a/src/libcore/iter.rs
+++ b/src/libcore/iter.rs
@@ -2701,63 +2701,93 @@ impl<A: Int> Iterator for RangeStepInclusive<A> {
     }
 }
 
-
-/// The `Step` trait identifies objects which can be stepped over in both
-/// directions. The `steps_between` function provides a way to
-/// compare two Step objects (it could be provided using `step()` and `Ord`,
-/// but the implementation would be so inefficient as to be useless).
-#[unstable = "design of range notation/iteration is in flux"]
-pub trait Step: Ord {
-    /// Change self to the next object.
-    fn step(&mut self);
-    /// Change self to the previous object.
-    fn step_back(&mut self);
-    /// The steps_between two step objects.
-    /// start should always be less than end, so the result should never be negative.
-    /// Return None if it is not possible to calculate steps_between without
-    /// overflow.
-    fn steps_between(start: &Self, end: &Self) -> Option<uint>;
-}
-
-macro_rules! step_impl {
+macro_rules! range_impl {
     ($($t:ty)*) => ($(
-        #[unstable = "Trait is unstable."]
-        impl Step for $t {
-            #[inline]
-            fn step(&mut self) { *self += 1; }
+        #[stable]
+        impl Iterator for ::ops::Range<$t> {
+            type Item = $t;
+
             #[inline]
-            fn step_back(&mut self) { *self -= 1; }
+            fn next(&mut self) -> Option<$t> {
+                if self.start < self.end {
+                    let result = self.start;
+                    self.start += 1;
+                    return Some(result);
+                }
+
+                return None;
+            }
+
             #[inline]
-            fn steps_between(start: &$t, end: &$t) -> Option<uint> {
-                debug_assert!(end >= start);
-                Some((*end - *start) as uint)
+            fn size_hint(&self) -> (uint, Option<uint>) {
+                debug_assert!(self.end >= self.start);
+                let hint = (self.end - self.start) as uint;
+                (hint, Some(hint))
             }
         }
+
+        #[stable]
+        impl ExactSizeIterator for ::ops::Range<$t> {}
     )*)
 }
 
-macro_rules! step_impl_no_between {
+macro_rules! range_impl_no_hint {
     ($($t:ty)*) => ($(
-        #[unstable = "Trait is unstable."]
-        impl Step for $t {
+        #[stable]
+        impl Iterator for ::ops::Range<$t> {
+            type Item = $t;
+
             #[inline]
-            fn step(&mut self) { *self += 1; }
+            fn next(&mut self) -> Option<$t> {
+                if self.start < self.end {
+                    let result = self.start;
+                    self.start += 1;
+                    return Some(result);
+                }
+
+                return None;
+            }
+        }
+    )*)
+}
+
+macro_rules! range_other_impls {
+    ($($t:ty)*) => ($(
+        #[stable]
+        impl DoubleEndedIterator for ::ops::Range<$t> {
             #[inline]
-            fn step_back(&mut self) { *self -= 1; }
+            fn next_back(&mut self) -> Option<$t> {
+                if self.start < self.end {
+                    self.end -= 1;
+                    return Some(self.end);
+                }
+
+                return None;
+            }
+        }
+
+        #[stable]
+        impl Iterator for ::ops::RangeFrom<$t> {
+            type Item = $t;
+
             #[inline]
-            fn steps_between(_start: &$t, _end: &$t) -> Option<uint> {
-                None
+            fn next(&mut self) -> Option<$t> {
+                let result = self.start;
+                self.start += 1;
+                debug_assert!(result < self.start);
+                return Some(result);
             }
         }
     )*)
 }
 
-step_impl!(uint u8 u16 u32 int i8 i16 i32);
+range_impl!(uint u8 u16 u32 int i8 i16 i32);
 #[cfg(target_pointer_width = "64")]
-step_impl!(u64 i64);
+range_impl!(u64 i64);
 #[cfg(target_pointer_width = "32")]
-step_impl_no_between!(u64 i64);
+range_impl_no_hint!(u64 i64);
 
+range_other_impls!(uint u8 u16 u32 u64 int i8 i16 i32 i64);
 
 /// An iterator that repeats an element endlessly
 #[derive(Clone)]