Skip to content

Commit c98f0cb

Browse files
committed
vec: add an external iterator
1 parent c2f5a87 commit c98f0cb

File tree

1 file changed

+54
-1
lines changed

1 file changed

+54
-1
lines changed

src/libcore/vec.rs

+54-1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@ use cmp::{Eq, Ord, TotalEq, TotalOrd, Ordering, Less, Equal, Greater};
1818
use clone::Clone;
1919
use iter::BaseIter;
2020
use iter;
21+
#[cfg(stage1)]
22+
#[cfg(stage2)]
23+
#[cfg(stage3)]
24+
use iterator::Iterator;
2125
use kinds::Copy;
2226
use libc;
2327
use option::{None, Option, Some};
@@ -1919,6 +1923,7 @@ impl<'self,T> ImmutableVector<T> for &'self [T] {
19191923
#[cfg(stage3)]
19201924
pub trait ImmutableVector<'self, T> {
19211925
fn slice(&self, start: uint, end: uint) -> &'self [T];
1926+
fn iter(self) -> VecIterator<'self, T>;
19221927
fn head(&self) -> &'self T;
19231928
fn head_opt(&self) -> Option<&'self T>;
19241929
fn tail(&self) -> &'self [T];
@@ -1949,6 +1954,15 @@ impl<'self,T> ImmutableVector<'self, T> for &'self [T] {
19491954
slice(*self, start, end)
19501955
}
19511956

1957+
#[inline]
1958+
fn iter(self) -> VecIterator<'self, T> {
1959+
unsafe {
1960+
let p = vec::raw::to_ptr(self);
1961+
VecIterator{ptr: p, end: p.offset(self.len()),
1962+
lifetime: cast::transmute(p)}
1963+
}
1964+
}
1965+
19521966
/// Returns the first element of a vector, failing if the vector is empty.
19531967
#[inline]
19541968
fn head(&self) -> &'self T { head(*self) }
@@ -2795,7 +2809,33 @@ impl<A:Clone> Clone for ~[A] {
27952809
}
27962810
}
27972811

2798-
// ___________________________________________________________________________
2812+
// could be implemented with &[T] with .slice(), but this avoids bounds checks
2813+
#[cfg(stage1)]
2814+
#[cfg(stage2)]
2815+
#[cfg(stage3)]
2816+
pub struct VecIterator<'self, T> {
2817+
priv ptr: *T,
2818+
priv end: *T,
2819+
priv lifetime: &'self T // FIXME: #5922
2820+
}
2821+
2822+
#[cfg(stage1)]
2823+
#[cfg(stage2)]
2824+
#[cfg(stage3)]
2825+
impl<'self, T> Iterator<&'self T> for VecIterator<'self, T> {
2826+
#[inline]
2827+
fn next(&mut self) -> Option<&'self T> {
2828+
unsafe {
2829+
if self.ptr == self.end {
2830+
None
2831+
} else {
2832+
let old = self.ptr;
2833+
self.ptr = self.ptr.offset(1);
2834+
Some(cast::transmute(old))
2835+
}
2836+
}
2837+
}
2838+
}
27992839

28002840
#[cfg(test)]
28012841
mod tests {
@@ -4421,6 +4461,19 @@ mod tests {
44214461
[1, 2, 3, 4, 5, 5, 5, 5].cmp(& &[1, 2, 3, 4, 5, 6]) == Less;
44224462
[2, 2].cmp(& &[1, 2, 3, 4]) == Greater;
44234463
}
4464+
4465+
#[test]
4466+
fn test_iterator() {
4467+
use iterator::*;
4468+
let xs = [1, 2, 5, 10, 11];
4469+
let ys = [1, 2, 5, 10, 11, 19];
4470+
let mut it = xs.iter();
4471+
let mut i = 0;
4472+
for it.advance |&x| {
4473+
assert_eq!(x, ys[i]);
4474+
i += 1;
4475+
}
4476+
}
44244477
}
44254478

44264479
// Local Variables:

0 commit comments

Comments
 (0)