Skip to content

Commit 799d9fa

Browse files
committed
auto merge of #6560 : gifnksm/rust/iterator-utils, r=thestinger
This pull request adds following methods and traits. ```rust pub trait IteratorUtil { (snip) fn filter_map<'r, B>(self, f: &'r fn(A) -> Option<B>) -> FilterMapIterator<'r, A, B, Self>; (snip) fn to_vec(self) -> ~[A]; fn nth(&mut self, n: uint) -> A; fn first(&mut self) -> A; fn last(&mut self) -> 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; fn any(&mut self, f: &fn(&A) -> bool) -> bool; } pub trait AdditiveIterator<A> { fn sum(&mut self) -> A; } pub trait MultiplicativeIterator<A> { fn product(&mut self) -> A; } pub trait OrdIterator<A> { fn max(&mut self) -> Option<A>; fn min(&mut self) -> Option<A>; } ```
2 parents d68c027 + 3122d80 commit 799d9fa

File tree

1 file changed

+262
-0
lines changed

1 file changed

+262
-0
lines changed

src/libcore/iterator.rs

+262
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ implementing the `Iterator` trait.
1818
*/
1919

2020
use prelude::*;
21+
use num::{Zero, One};
2122

2223
pub trait Iterator<A> {
2324
/// Advance the iterator and return the next value. Return `None` when the end is reached.
@@ -34,6 +35,7 @@ pub trait IteratorUtil<A> {
3435
// FIXME: #5898: should be called map
3536
fn transform<'r, B>(self, f: &'r fn(A) -> B) -> MapIterator<'r, A, B, Self>;
3637
fn filter<'r>(self, predicate: &'r fn(&A) -> bool) -> FilterIterator<'r, A, Self>;
38+
fn filter_map<'r, B>(self, f: &'r fn(A) -> Option<B>) -> FilterMapIterator<'r, A, B, Self>;
3739
fn enumerate(self) -> EnumerateIterator<Self>;
3840
fn skip_while<'r>(self, predicate: &'r fn(&A) -> bool) -> SkipWhileIterator<'r, A, Self>;
3941
fn take_while<'r>(self, predicate: &'r fn(&A) -> bool) -> TakeWhileIterator<'r, A, Self>;
@@ -45,6 +47,14 @@ pub trait IteratorUtil<A> {
4547
fn advance(&mut self, f: &fn(A) -> bool);
4648
#[cfg(not(stage0))]
4749
fn advance(&mut self, f: &fn(A) -> bool) -> bool;
50+
fn to_vec(self) -> ~[A];
51+
fn nth(&mut self, n: uint) -> A;
52+
fn first(&mut self) -> A;
53+
fn last(&mut self) -> A;
54+
fn fold<B>(&mut self, start: B, f: &fn(B, A) -> B) -> B;
55+
fn count(&mut self) -> uint;
56+
fn all(&mut self, f: &fn(&A) -> bool) -> bool;
57+
fn any(&mut self, f: &fn(&A) -> bool) -> bool;
4858
}
4959

5060
/// Iterator adaptors provided for every `Iterator` implementation. The adaptor objects are also
@@ -73,6 +83,11 @@ impl<A, T: Iterator<A>> IteratorUtil<A> for T {
7383
FilterIterator{iter: self, predicate: predicate}
7484
}
7585

86+
#[inline(always)]
87+
fn filter_map<'r, B>(self, f: &'r fn(A) -> Option<B>) -> FilterMapIterator<'r, A, B, T> {
88+
FilterMapIterator { iter: self, f: f }
89+
}
90+
7691
#[inline(always)]
7792
fn enumerate(self) -> EnumerateIterator<T> {
7893
EnumerateIterator{iter: self, count: 0}
@@ -131,6 +146,123 @@ impl<A, T: Iterator<A>> IteratorUtil<A> for T {
131146
}
132147
}
133148
}
149+
150+
#[inline(always)]
151+
fn to_vec(self) -> ~[A] {
152+
let mut v = ~[];
153+
let mut it = self;
154+
for it.advance() |x| { v.push(x); }
155+
return v;
156+
}
157+
158+
/// Get `n`th element of an iterator.
159+
#[inline(always)]
160+
fn nth(&mut self, n: uint) -> A {
161+
let mut i = n;
162+
loop {
163+
match self.next() {
164+
Some(x) => { if i == 0 { return x; }}
165+
None => { fail!("cannot get %uth element", n) }
166+
}
167+
i -= 1;
168+
}
169+
}
170+
171+
// Get first elemet of an iterator.
172+
#[inline(always)]
173+
fn first(&mut self) -> A {
174+
match self.next() {
175+
Some(x) => x ,
176+
None => fail!("cannot get first element")
177+
}
178+
}
179+
180+
// Get last element of an iterator.
181+
//
182+
// If the iterator have an infinite length, this method won't return.
183+
#[inline(always)]
184+
fn last(&mut self) -> A {
185+
let mut elm = match self.next() {
186+
Some(x) => x,
187+
None => fail!("cannot get last element")
188+
};
189+
for self.advance |e| { elm = e; }
190+
return elm;
191+
}
192+
193+
/// Reduce an iterator to an accumulated value
194+
#[inline]
195+
fn fold<B>(&mut self, init: B, f: &fn(B, A) -> B) -> B {
196+
let mut accum = init;
197+
loop {
198+
match self.next() {
199+
Some(x) => { accum = f(accum, x); }
200+
None => { break; }
201+
}
202+
}
203+
return accum;
204+
}
205+
206+
/// Count the number of an iterator elemenrs
207+
#[inline(always)]
208+
fn count(&mut self) -> uint { self.fold(0, |cnt, _x| cnt + 1) }
209+
210+
#[inline(always)]
211+
fn all(&mut self, f: &fn(&A) -> bool) -> bool {
212+
for self.advance |x| { if !f(&x) { return false; } }
213+
return true;
214+
}
215+
216+
#[inline(always)]
217+
fn any(&mut self, f: &fn(&A) -> bool) -> bool {
218+
for self.advance |x| { if f(&x) { return true; } }
219+
return false;
220+
}
221+
}
222+
223+
pub trait AdditiveIterator<A> {
224+
fn sum(&mut self) -> A;
225+
}
226+
227+
impl<A: Add<A, A> + Zero, T: Iterator<A>> AdditiveIterator<A> for T {
228+
#[inline(always)]
229+
fn sum(&mut self) -> A { self.fold(Zero::zero::<A>(), |s, x| s + x) }
230+
}
231+
232+
pub trait MultiplicativeIterator<A> {
233+
fn product(&mut self) -> A;
234+
}
235+
236+
impl<A: Mul<A, A> + One, T: Iterator<A>> MultiplicativeIterator<A> for T {
237+
#[inline(always)]
238+
fn product(&mut self) -> A { self.fold(One::one::<A>(), |p, x| p * x) }
239+
}
240+
241+
pub trait OrdIterator<A> {
242+
fn max(&mut self) -> Option<A>;
243+
fn min(&mut self) -> Option<A>;
244+
}
245+
246+
impl<A: Ord, T: Iterator<A>> OrdIterator<A> for T {
247+
#[inline(always)]
248+
fn max(&mut self) -> Option<A> {
249+
self.fold(None, |max, x| {
250+
match max {
251+
None => Some(x),
252+
Some(y) => Some(cmp::max(x, y))
253+
}
254+
})
255+
}
256+
257+
#[inline(always)]
258+
fn min(&mut self) -> Option<A> {
259+
self.fold(None, |min, x| {
260+
match min {
261+
None => Some(x),
262+
Some(y) => Some(cmp::min(x, y))
263+
}
264+
})
265+
}
134266
}
135267

136268
pub struct ChainIterator<T, U> {
@@ -204,6 +336,28 @@ impl<'self, A, T: Iterator<A>> Iterator<A> for FilterIterator<'self, A, T> {
204336
}
205337
}
206338

339+
pub struct FilterMapIterator<'self, A, B, T> {
340+
priv iter: T,
341+
priv f: &'self fn(A) -> Option<B>
342+
}
343+
344+
impl<'self, A, B, T: Iterator<A>> Iterator<B> for FilterMapIterator<'self, A, B, T> {
345+
#[inline]
346+
fn next(&mut self) -> Option<B> {
347+
loop {
348+
match self.iter.next() {
349+
None => { return None; }
350+
Some(a) => {
351+
match (self.f)(a) {
352+
Some(b) => { return Some(b); }
353+
None => { loop; }
354+
}
355+
}
356+
}
357+
}
358+
}
359+
}
360+
207361
pub struct EnumerateIterator<T> {
208362
priv iter: T,
209363
priv count: uint
@@ -423,6 +577,13 @@ mod tests {
423577
assert_eq!(i, expected.len());
424578
}
425579

580+
#[test]
581+
fn test_filter_map() {
582+
let it = Counter::new(0u, 1u).take(10)
583+
.filter_map(|x: uint| if x.is_even() { Some(x*x) } else { None });
584+
assert_eq!(it.to_vec(), ~[0*0, 2*2, 4*4, 6*6, 8*8]);
585+
}
586+
426587
#[test]
427588
fn test_iterator_enumerate() {
428589
let xs = [0u, 1, 2, 3, 4, 5];
@@ -523,4 +684,105 @@ mod tests {
523684
}
524685
assert_eq!(i, 10);
525686
}
687+
688+
#[test]
689+
fn test_iterator_nth() {
690+
let v = &[0, 1, 2, 3, 4];
691+
for uint::range(0, v.len()) |i| {
692+
assert_eq!(v.iter().nth(i), &v[i]);
693+
}
694+
}
695+
696+
#[test]
697+
#[should_fail]
698+
fn test_iterator_nth_fail() {
699+
let v = &[0, 1, 2, 3, 4];
700+
v.iter().nth(5);
701+
}
702+
703+
#[test]
704+
fn test_iterator_first() {
705+
let v = &[0, 1, 2, 3, 4];
706+
assert_eq!(v.iter().first(), &0);
707+
assert_eq!(v.slice(2, 5).iter().first(), &2);
708+
}
709+
710+
#[test]
711+
#[should_fail]
712+
fn test_iterator_first_fail() {
713+
let v: &[uint] = &[];
714+
v.iter().first();
715+
}
716+
717+
#[test]
718+
fn test_iterator_last() {
719+
let v = &[0, 1, 2, 3, 4];
720+
assert_eq!(v.iter().last(), &4);
721+
assert_eq!(v.slice(0, 1).iter().last(), &0);
722+
}
723+
724+
#[test]
725+
#[should_fail]
726+
fn test_iterator_last_fail() {
727+
let v: &[uint] = &[];
728+
v.iter().last();
729+
}
730+
731+
#[test]
732+
fn test_iterator_count() {
733+
let v = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
734+
assert_eq!(v.slice(0, 4).iter().count(), 4);
735+
assert_eq!(v.slice(0, 10).iter().count(), 10);
736+
assert_eq!(v.slice(0, 0).iter().count(), 0);
737+
}
738+
739+
#[test]
740+
fn test_iterator_sum() {
741+
let v = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
742+
assert_eq!(v.slice(0, 4).iter().transform(|&x| x).sum(), 6);
743+
assert_eq!(v.iter().transform(|&x| x).sum(), 55);
744+
assert_eq!(v.slice(0, 0).iter().transform(|&x| x).sum(), 0);
745+
}
746+
747+
#[test]
748+
fn test_iterator_product() {
749+
let v = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
750+
assert_eq!(v.slice(0, 4).iter().transform(|&x| x).product(), 0);
751+
assert_eq!(v.slice(1, 5).iter().transform(|&x| x).product(), 24);
752+
assert_eq!(v.slice(0, 0).iter().transform(|&x| x).product(), 1);
753+
}
754+
755+
#[test]
756+
fn test_iterator_max() {
757+
let v = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
758+
assert_eq!(v.slice(0, 4).iter().transform(|&x| x).max(), Some(3));
759+
assert_eq!(v.iter().transform(|&x| x).max(), Some(10));
760+
assert_eq!(v.slice(0, 0).iter().transform(|&x| x).max(), None);
761+
}
762+
763+
#[test]
764+
fn test_iterator_min() {
765+
let v = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
766+
assert_eq!(v.slice(0, 4).iter().transform(|&x| x).min(), Some(0));
767+
assert_eq!(v.iter().transform(|&x| x).min(), Some(0));
768+
assert_eq!(v.slice(0, 0).iter().transform(|&x| x).min(), None);
769+
}
770+
771+
#[test]
772+
fn test_all() {
773+
let v = ~&[1, 2, 3, 4, 5];
774+
assert!(v.iter().all(|&x| *x < 10));
775+
assert!(!v.iter().all(|&x| x.is_even()));
776+
assert!(!v.iter().all(|&x| *x > 100));
777+
assert!(v.slice(0, 0).iter().all(|_| fail!()));
778+
}
779+
780+
#[test]
781+
fn test_any() {
782+
let v = ~&[1, 2, 3, 4, 5];
783+
assert!(v.iter().any(|&x| *x < 10));
784+
assert!(v.iter().any(|&x| x.is_even()));
785+
assert!(!v.iter().any(|&x| *x > 100));
786+
assert!(!v.slice(0, 0).iter().any(|_| fail!()));
787+
}
526788
}

0 commit comments

Comments
 (0)