Skip to content

tweaks to core::iterator #6589

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 6 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
103 changes: 27 additions & 76 deletions src/libcore/iterator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,10 @@ pub trait IteratorUtil<A> {
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<A>;
fn last(&mut self) -> Option<A>;
fn fold<B>(&mut self, start: B, f: &fn(B, A) -> B) -> B;
fn count(&mut self) -> uint;
fn all(&mut self, f: &fn(&A) -> bool) -> bool;
Expand Down Expand Up @@ -147,47 +147,30 @@ impl<A, T: Iterator<A>> IteratorUtil<A> 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::<A>(|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<A> {
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<A> {
let mut last = None;
for self.advance |x| { last = Some(x); }
last
}

/// Reduce an iterator to an accumulated value
Expand All @@ -203,7 +186,7 @@ impl<A, T: Iterator<A>> IteratorUtil<A> 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) }

Expand Down Expand Up @@ -344,17 +327,13 @@ pub struct FilterMapIterator<'self, A, B, T> {
impl<'self, A, B, T: Iterator<A>> Iterator<B> for FilterMapIterator<'self, A, B, T> {
#[inline]
fn next(&mut self) -> Option<B> {
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
}
}

Expand Down Expand Up @@ -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]);
}
Expand Down Expand Up @@ -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]
Expand Down