diff --git a/src/libcore/iterator.rs b/src/libcore/iterator.rs index 588bd0bde5343..ecf76a39fcdb5 100644 --- a/src/libcore/iterator.rs +++ b/src/libcore/iterator.rs @@ -47,10 +47,10 @@ pub trait IteratorUtil { fn advance(&mut self, f: &fn(A) -> bool); #[cfg(not(stage0))] fn advance(&mut self, f: &fn(A) -> bool) -> bool; - fn to_vec(self) -> ~[A]; - fn nth(&mut self, n: uint) -> A; - fn first(&mut self) -> A; - fn last(&mut self) -> A; + #[cfg(not(stage0))] + fn to_vec(&mut self) -> ~[A]; + fn nth(&mut self, n: uint) -> Option; + fn last(&mut self) -> Option; fn fold(&mut self, start: B, f: &fn(B, A) -> B) -> B; fn count(&mut self) -> uint; fn all(&mut self, f: &fn(&A) -> bool) -> bool; @@ -147,47 +147,30 @@ impl> IteratorUtil for T { } } + #[cfg(not(stage0))] #[inline(always)] - fn to_vec(self) -> ~[A] { - let mut v = ~[]; - let mut it = self; - for it.advance() |x| { v.push(x); } - return v; + fn to_vec(&mut self) -> ~[A] { + iter::to_vec::(|f| self.advance(f)) } - /// Get `n`th element of an iterator. + /// Return the `n`th item yielded by an iterator. #[inline(always)] - fn nth(&mut self, n: uint) -> A { - let mut i = n; + fn nth(&mut self, mut n: uint) -> Option { loop { match self.next() { - Some(x) => { if i == 0 { return x; }} - None => { fail!("cannot get %uth element", n) } + Some(x) => if n == 0 { return Some(x) }, + None => return None } - i -= 1; + n -= 1; } } - // Get first elemet of an iterator. + /// Return the last item yielded by an iterator. #[inline(always)] - fn first(&mut self) -> A { - match self.next() { - Some(x) => x , - None => fail!("cannot get first element") - } - } - - // Get last element of an iterator. - // - // If the iterator have an infinite length, this method won't return. - #[inline(always)] - fn last(&mut self) -> A { - let mut elm = match self.next() { - Some(x) => x, - None => fail!("cannot get last element") - }; - for self.advance |e| { elm = e; } - return elm; + fn last(&mut self) -> Option { + let mut last = None; + for self.advance |x| { last = Some(x); } + last } /// Reduce an iterator to an accumulated value @@ -203,7 +186,7 @@ impl> IteratorUtil for T { return accum; } - /// Count the number of an iterator elemenrs + /// Count the number of items yielded by an iterator #[inline(always)] fn count(&mut self) -> uint { self.fold(0, |cnt, _x| cnt + 1) } @@ -344,17 +327,13 @@ pub struct FilterMapIterator<'self, A, B, T> { impl<'self, A, B, T: Iterator> Iterator for FilterMapIterator<'self, A, B, T> { #[inline] fn next(&mut self) -> Option { - loop { - match self.iter.next() { - None => { return None; } - Some(a) => { - match (self.f)(a) { - Some(b) => { return Some(b); } - None => { loop; } - } - } + for self.iter.advance |x| { + match (self.f)(x) { + Some(y) => return Some(y), + None => () } } + None } } @@ -579,7 +558,7 @@ mod tests { #[test] fn test_filter_map() { - let it = Counter::new(0u, 1u).take(10) + let mut it = Counter::new(0u, 1u).take(10) .filter_map(|x: uint| if x.is_even() { Some(x*x) } else { None }); assert_eq!(it.to_vec(), ~[0*0, 2*2, 4*4, 6*6, 8*8]); } @@ -689,43 +668,15 @@ mod tests { fn test_iterator_nth() { let v = &[0, 1, 2, 3, 4]; for uint::range(0, v.len()) |i| { - assert_eq!(v.iter().nth(i), &v[i]); + assert_eq!(v.iter().nth(i).unwrap(), &v[i]); } } - #[test] - #[should_fail] - fn test_iterator_nth_fail() { - let v = &[0, 1, 2, 3, 4]; - v.iter().nth(5); - } - - #[test] - fn test_iterator_first() { - let v = &[0, 1, 2, 3, 4]; - assert_eq!(v.iter().first(), &0); - assert_eq!(v.slice(2, 5).iter().first(), &2); - } - - #[test] - #[should_fail] - fn test_iterator_first_fail() { - let v: &[uint] = &[]; - v.iter().first(); - } - #[test] fn test_iterator_last() { let v = &[0, 1, 2, 3, 4]; - assert_eq!(v.iter().last(), &4); - assert_eq!(v.slice(0, 1).iter().last(), &0); - } - - #[test] - #[should_fail] - fn test_iterator_last_fail() { - let v: &[uint] = &[]; - v.iter().last(); + assert_eq!(v.iter().last().unwrap(), &4); + assert_eq!(v.slice(0, 1).iter().last().unwrap(), &0); } #[test]