diff --git a/src/libcore/vec.rs b/src/libcore/vec.rs index 30201304d61..0403ae64f02 100644 --- a/src/libcore/vec.rs +++ b/src/libcore/vec.rs @@ -18,6 +18,10 @@ use cmp::{Eq, Ord, TotalEq, TotalOrd, Ordering, Less, Equal, Greater}; use clone::Clone; use iter::BaseIter; use iter; +#[cfg(stage1)] +#[cfg(stage2)] +#[cfg(stage3)] +use iterator::Iterator; use kinds::Copy; use libc; use option::{None, Option, Some}; @@ -1919,6 +1923,7 @@ impl<'self,T> ImmutableVector for &'self [T] { #[cfg(stage3)] pub trait ImmutableVector<'self, T> { fn slice(&self, start: uint, end: uint) -> &'self [T]; + fn iter(self) -> VecIterator<'self, T>; fn head(&self) -> &'self T; fn head_opt(&self) -> Option<&'self T>; fn tail(&self) -> &'self [T]; @@ -1949,6 +1954,15 @@ impl<'self,T> ImmutableVector<'self, T> for &'self [T] { slice(*self, start, end) } + #[inline] + fn iter(self) -> VecIterator<'self, T> { + unsafe { + let p = vec::raw::to_ptr(self); + VecIterator{ptr: p, end: p.offset(self.len()), + lifetime: cast::transmute(p)} + } + } + /// Returns the first element of a vector, failing if the vector is empty. #[inline] fn head(&self) -> &'self T { head(*self) } @@ -2795,7 +2809,33 @@ impl Clone for ~[A] { } } -// ___________________________________________________________________________ +// could be implemented with &[T] with .slice(), but this avoids bounds checks +#[cfg(stage1)] +#[cfg(stage2)] +#[cfg(stage3)] +pub struct VecIterator<'self, T> { + priv ptr: *T, + priv end: *T, + priv lifetime: &'self T // FIXME: #5922 +} + +#[cfg(stage1)] +#[cfg(stage2)] +#[cfg(stage3)] +impl<'self, T> Iterator<&'self T> for VecIterator<'self, T> { + #[inline] + fn next(&mut self) -> Option<&'self T> { + unsafe { + if self.ptr == self.end { + None + } else { + let old = self.ptr; + self.ptr = self.ptr.offset(1); + Some(cast::transmute(old)) + } + } + } +} #[cfg(test)] mod tests { @@ -4421,6 +4461,19 @@ mod tests { [1, 2, 3, 4, 5, 5, 5, 5].cmp(& &[1, 2, 3, 4, 5, 6]) == Less; [2, 2].cmp(& &[1, 2, 3, 4]) == Greater; } + + #[test] + fn test_iterator() { + use iterator::*; + let xs = [1, 2, 5, 10, 11]; + let ys = [1, 2, 5, 10, 11, 19]; + let mut it = xs.iter(); + let mut i = 0; + for it.advance |&x| { + assert_eq!(x, ys[i]); + i += 1; + } + } } // Local Variables: