From a9c465ce1f1caaae58a31c57f665217ee58bb876 Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Sat, 18 May 2013 04:20:01 -0400 Subject: [PATCH 1/6] iterator: remove `first` it's the same as `next.unwrap()`, but there's no way to check the length of an iterator so this isn't a good pattern --- src/libcore/iterator.rs | 24 ------------------------ 1 file changed, 24 deletions(-) diff --git a/src/libcore/iterator.rs b/src/libcore/iterator.rs index 588bd0bde5343..68281526e6f94 100644 --- a/src/libcore/iterator.rs +++ b/src/libcore/iterator.rs @@ -49,7 +49,6 @@ pub trait IteratorUtil { 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; fn fold(&mut self, start: B, f: &fn(B, A) -> B) -> B; fn count(&mut self) -> uint; @@ -168,15 +167,6 @@ impl> IteratorUtil for T { } } - // 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. @@ -700,20 +690,6 @@ mod tests { 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]; From ea8a55b821460ef7b3b58052f99673674fca8f96 Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Sat, 18 May 2013 04:27:58 -0400 Subject: [PATCH 2/6] iterator: make nth and last return Option There isn't a way to take the length of any iterator, so failing on a zero length would make these much less useful. --- src/libcore/iterator.rs | 50 +++++++++++++---------------------------- 1 file changed, 15 insertions(+), 35 deletions(-) diff --git a/src/libcore/iterator.rs b/src/libcore/iterator.rs index 68281526e6f94..65c36b122c766 100644 --- a/src/libcore/iterator.rs +++ b/src/libcore/iterator.rs @@ -48,8 +48,8 @@ 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 last(&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; @@ -154,30 +154,24 @@ impl> IteratorUtil for T { return v; } - /// 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 last element of an iterator. - // - // If the iterator have an infinite length, this method won't return. + /// Return the last item yielded by an iterator. #[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 @@ -679,29 +673,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_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] From 883d583faa9f33e69dce4b913f47a2d09e8b584d Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Sat, 18 May 2013 04:32:53 -0400 Subject: [PATCH 3/6] iterator: reuse iter::to_vec, and use &mut self --- src/libcore/iterator.rs | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/libcore/iterator.rs b/src/libcore/iterator.rs index 65c36b122c766..0b0df4a5d70b7 100644 --- a/src/libcore/iterator.rs +++ b/src/libcore/iterator.rs @@ -47,7 +47,7 @@ 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 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; @@ -147,11 +147,8 @@ impl> IteratorUtil for T { } #[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)) } /// Return the `n`th item yielded by an iterator. @@ -563,7 +560,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]); } From 073225572a1c7c7dc9f7c2740514557105950807 Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Sat, 18 May 2013 04:44:44 -0400 Subject: [PATCH 4/6] iterator: reword docstring --- src/libcore/iterator.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcore/iterator.rs b/src/libcore/iterator.rs index 0b0df4a5d70b7..0bf61b66f7532 100644 --- a/src/libcore/iterator.rs +++ b/src/libcore/iterator.rs @@ -184,7 +184,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) } From fc656262a905a50eff2be54a87295d2952d29106 Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Sat, 18 May 2013 04:48:22 -0400 Subject: [PATCH 5/6] iterator: use advance to implement FilterMapIterator --- src/libcore/iterator.rs | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/src/libcore/iterator.rs b/src/libcore/iterator.rs index 0bf61b66f7532..41f916f2d1557 100644 --- a/src/libcore/iterator.rs +++ b/src/libcore/iterator.rs @@ -325,17 +325,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 } } From 9b6b0e1e646b42de7205a21bf73e5c4c2b203a6b Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Sat, 18 May 2013 22:10:56 -0400 Subject: [PATCH 6/6] fix stage0 compile --- src/libcore/iterator.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libcore/iterator.rs b/src/libcore/iterator.rs index 41f916f2d1557..ecf76a39fcdb5 100644 --- a/src/libcore/iterator.rs +++ b/src/libcore/iterator.rs @@ -47,6 +47,7 @@ pub trait IteratorUtil { fn advance(&mut self, f: &fn(A) -> bool); #[cfg(not(stage0))] fn advance(&mut self, f: &fn(A) -> bool) -> bool; + #[cfg(not(stage0))] fn to_vec(&mut self) -> ~[A]; fn nth(&mut self, n: uint) -> Option; fn last(&mut self) -> Option; @@ -146,6 +147,7 @@ impl> IteratorUtil for T { } } + #[cfg(not(stage0))] #[inline(always)] fn to_vec(&mut self) -> ~[A] { iter::to_vec::(|f| self.advance(f))