diff --git a/src/libcore/iterator.rs b/src/libcore/iterator.rs index 685b4fcac7f..14d6083067a 100644 --- a/src/libcore/iterator.rs +++ b/src/libcore/iterator.rs @@ -47,6 +47,9 @@ pub trait IteratorUtil { #[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; } /// Iterator adaptors provided for every `Iterator` implementation. The adaptor objects are also @@ -146,6 +149,41 @@ impl> IteratorUtil for T { for it.advance() |x| { v.push(x); } return v; } + + /// Get `n`th element of an iterator. + #[inline(always)] + fn nth(&mut self, n: uint) -> A { + let mut i = n; + loop { + match self.next() { + Some(x) => { if i == 0 { return x; }} + None => { fail!("cannot get %uth element", n) } + } + i -= 1; + } + } + + // Get first elemet of 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; + } } pub struct ChainIterator { @@ -567,4 +605,47 @@ mod tests { } assert_eq!(i, 10); } + + #[test] + 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]); + } + } + + #[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(); + } }