about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/libcollections/vec.rs12
-rw-r--r--src/libcore/iter.rs104
-rw-r--r--src/libcore/ops.rs75
3 files changed, 89 insertions, 102 deletions
diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs
index 4ddab8c533a..7596973ea23 100644
--- a/src/libcollections/vec.rs
+++ b/src/libcollections/vec.rs
@@ -1229,7 +1229,7 @@ impl<S: hash::Writer + hash::Hasher, T: Hash<S>> Hash<S> for Vec<T> {
     }
 }
 
-#[unstable = "waiting on Index stability"]
+#[stable]
 impl<T> Index<uint> for Vec<T> {
     type Output = T;
 
@@ -1239,6 +1239,7 @@ impl<T> Index<uint> for Vec<T> {
     }
 }
 
+#[stable]
 impl<T> IndexMut<uint> for Vec<T> {
     type Output = T;
 
@@ -1249,6 +1250,7 @@ impl<T> IndexMut<uint> for Vec<T> {
 }
 
 
+#[stable]
 impl<T> ops::Index<ops::Range<uint>> for Vec<T> {
     type Output = [T];
     #[inline]
@@ -1256,6 +1258,7 @@ impl<T> ops::Index<ops::Range<uint>> for Vec<T> {
         self.as_slice().index(index)
     }
 }
+#[stable]
 impl<T> ops::Index<ops::RangeTo<uint>> for Vec<T> {
     type Output = [T];
     #[inline]
@@ -1263,6 +1266,7 @@ impl<T> ops::Index<ops::RangeTo<uint>> for Vec<T> {
         self.as_slice().index(index)
     }
 }
+#[stable]
 impl<T> ops::Index<ops::RangeFrom<uint>> for Vec<T> {
     type Output = [T];
     #[inline]
@@ -1270,6 +1274,7 @@ impl<T> ops::Index<ops::RangeFrom<uint>> for Vec<T> {
         self.as_slice().index(index)
     }
 }
+#[stable]
 impl<T> ops::Index<ops::FullRange> for Vec<T> {
     type Output = [T];
     #[inline]
@@ -1278,6 +1283,7 @@ impl<T> ops::Index<ops::FullRange> for Vec<T> {
     }
 }
 
+#[stable]
 impl<T> ops::IndexMut<ops::Range<uint>> for Vec<T> {
     type Output = [T];
     #[inline]
@@ -1285,6 +1291,7 @@ impl<T> ops::IndexMut<ops::Range<uint>> for Vec<T> {
         self.as_mut_slice().index_mut(index)
     }
 }
+#[stable]
 impl<T> ops::IndexMut<ops::RangeTo<uint>> for Vec<T> {
     type Output = [T];
     #[inline]
@@ -1292,6 +1299,7 @@ impl<T> ops::IndexMut<ops::RangeTo<uint>> for Vec<T> {
         self.as_mut_slice().index_mut(index)
     }
 }
+#[stable]
 impl<T> ops::IndexMut<ops::RangeFrom<uint>> for Vec<T> {
     type Output = [T];
     #[inline]
@@ -1299,6 +1307,7 @@ impl<T> ops::IndexMut<ops::RangeFrom<uint>> for Vec<T> {
         self.as_mut_slice().index_mut(index)
     }
 }
+#[stable]
 impl<T> ops::IndexMut<ops::FullRange> for Vec<T> {
     type Output = [T];
     #[inline]
@@ -1307,7 +1316,6 @@ impl<T> ops::IndexMut<ops::FullRange> for Vec<T> {
     }
 }
 
-
 #[stable]
 impl<T> ops::Deref for Vec<T> {
     type Target = [T];
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)]
diff --git a/src/libcore/ops.rs b/src/libcore/ops.rs
index 905de9ef615..e5186f9335a 100644
--- a/src/libcore/ops.rs
+++ b/src/libcore/ops.rs
@@ -69,10 +69,7 @@
 
 #![stable]
 
-use clone::Clone;
-use iter::{Step, Iterator,DoubleEndedIterator,ExactSizeIterator};
 use marker::Sized;
-use option::Option::{self, Some, None};
 use fmt;
 
 /// The `Drop` trait is used to run some code when a value goes out of scope. This
@@ -924,10 +921,12 @@ shr_impl_all! { u8 u16 u32 u64 usize i8 i16 i32 i64 isize }
 /// }
 /// ```
 #[lang="index"]
+#[stable]
 pub trait Index<Index: ?Sized> {
     type Output: ?Sized;
 
     /// The method for the indexing (`Foo[Bar]`) operation
+    #[stable]
     fn index<'a>(&'a self, index: &Index) -> &'a Self::Output;
 }
 
@@ -960,20 +959,22 @@ pub trait Index<Index: ?Sized> {
 /// }
 /// ```
 #[lang="index_mut"]
+#[stable]
 pub trait IndexMut<Index: ?Sized> {
     type Output: ?Sized;
 
     /// The method for the indexing (`Foo[Bar]`) operation
+    #[stable]
     fn index_mut<'a>(&'a mut self, index: &Index) -> &'a mut Self::Output;
 }
 
 /// An unbounded range.
 #[derive(Copy, Clone, PartialEq, Eq)]
 #[lang="full_range"]
-#[unstable = "API still in development"]
+#[unstable = "may be renamed to RangeFull"]
 pub struct FullRange;
 
-#[unstable = "API still in development"]
+#[stable]
 impl fmt::Show for FullRange {
     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
         fmt::Show::fmt("..", fmt)
@@ -983,7 +984,7 @@ impl fmt::Show for FullRange {
 /// A (half-open) range which is bounded at both ends.
 #[derive(Copy, Clone, PartialEq, Eq)]
 #[lang="range"]
-#[unstable = "API still in development"]
+#[stable]
 pub struct Range<Idx> {
     /// The lower bound of the range (inclusive).
     pub start: Idx,
@@ -991,48 +992,7 @@ pub struct Range<Idx> {
     pub end: Idx,
 }
 
-#[unstable = "API still in development"]
-impl<Idx: Clone + Step> Iterator for Range<Idx> {
-    type Item = Idx;
-
-    #[inline]
-    fn next(&mut self) -> Option<Idx> {
-        if self.start < self.end {
-            let result = self.start.clone();
-            self.start.step();
-            return Some(result);
-        }
-
-        return None;
-    }
-
-    #[inline]
-    fn size_hint(&self) -> (uint, Option<uint>) {
-        if let Some(hint) = Step::steps_between(&self.start, &self.end) {
-            (hint, Some(hint))
-        } else {
-            (0, None)
-        }
-    }
-}
-
-#[unstable = "API still in development"]
-impl<Idx: Clone + Step> DoubleEndedIterator for Range<Idx> {
-    #[inline]
-    fn next_back(&mut self) -> Option<Idx> {
-        if self.start < self.end {
-            self.end.step_back();
-            return Some(self.end.clone());
-        }
-
-        return None;
-    }
-}
-
-#[unstable = "API still in development"]
-impl<Idx: Clone + Step> ExactSizeIterator for Range<Idx> {}
-
-#[unstable = "API still in development"]
+#[stable]
 impl<Idx: fmt::Show> fmt::Show for Range<Idx> {
     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
         write!(fmt, "{:?}..{:?}", self.start, self.end)
@@ -1042,26 +1002,15 @@ impl<Idx: fmt::Show> fmt::Show for Range<Idx> {
 /// A range which is only bounded below.
 #[derive(Copy, Clone, PartialEq, Eq)]
 #[lang="range_from"]
-#[unstable = "API still in development"]
+#[stable]
 pub struct RangeFrom<Idx> {
     /// The lower bound of the range (inclusive).
     pub start: Idx,
 }
 
-#[unstable = "API still in development"]
-impl<Idx: Clone + Step> Iterator for RangeFrom<Idx> {
-    type Item = Idx;
 
-    #[inline]
-    fn next(&mut self) -> Option<Idx> {
-        // Deliberately overflow so we loop forever.
-        let result = self.start.clone();
-        self.start.step();
-        return Some(result);
-    }
-}
 
-#[unstable = "API still in development"]
+#[stable]
 impl<Idx: fmt::Show> fmt::Show for RangeFrom<Idx> {
     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
         write!(fmt, "{:?}..", self.start)
@@ -1071,13 +1020,13 @@ impl<Idx: fmt::Show> fmt::Show for RangeFrom<Idx> {
 /// A range which is only bounded above.
 #[derive(Copy, Clone, PartialEq, Eq)]
 #[lang="range_to"]
-#[unstable = "API still in development"]
+#[stable]
 pub struct RangeTo<Idx> {
     /// The upper bound of the range (exclusive).
     pub end: Idx,
 }
 
-#[unstable = "API still in development"]
+#[stable]
 impl<Idx: fmt::Show> fmt::Show for RangeTo<Idx> {
     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
         write!(fmt, "..{:?}", self.end)