iface base_iter { fn each(blk: fn(A) -> bool); fn size_hint() -> option; } fn eachi>(self: IA, blk: fn(uint, A) -> bool) { let mut i = 0u; for self.each {|a| if !blk(i, a) { break; } i += 1u; } } fn all>(self: IA, blk: fn(A) -> bool) -> bool { for self.each {|a| if !blk(a) { ret false; } } ret true; } fn any>(self: IA, blk: fn(A) -> bool) -> bool { for self.each {|a| if blk(a) { ret true; } } ret false; } fn filter_to_vec>(self: IA, prd: fn(A) -> bool) -> [A] { let mut result = []; self.size_hint().iter {|hint| vec::reserve(result, hint); } for self.each {|a| if prd(a) { vec::push(result, a); } } ret result; } fn map_to_vec>(self: IA, op: fn(A) -> B) -> [B] { let mut result = []; self.size_hint().iter {|hint| vec::reserve(result, hint); } for self.each {|a| vec::push(result, op(a)); } ret result; } fn flat_map_to_vec,IB:base_iter>( self: IA, op: fn(A) -> IB) -> [B] { let mut result = []; for self.each {|a| for op(a).each {|b| vec::push(result, b); } } ret result; } fn foldl>(self: IA, +b0: B, blk: fn(B, A) -> B) -> B { let mut b <- b0; for self.each {|a| b = blk(b, a); } ret b; } fn to_vec>(self: IA) -> [A] { foldl::(self, [], {|r, a| r + [a]}) } fn contains>(self: IA, x: A) -> bool { for self.each {|a| if a == x { ret true; } } ret false; } fn count>(self: IA, x: A) -> uint { foldl(self, 0u) {|count, value| if value == x { count + 1u } else { count } } } fn repeat(times: uint, blk: fn()) { let mut i = 0u; while i < times { blk(); i += 1u; } } fn min>(self: IA) -> A { alt foldl::,IA>(self, none) {|a, b| alt a { some(a_) if a_ < b { // FIXME: Not sure if this is successfully optimized to a move // #2005 a } _ { some(b) } } } { some(val) { val } none { fail "min called on empty iterator" } } } fn max>(self: IA) -> A { alt foldl::,IA>(self, none) {|a, b| alt a { some(a_) if a_ > b { // FIXME: Not sure if this is successfully optimized to a move // #2005 a } _ { some(b) } } } { some(val) { val } none { fail "max called on empty iterator" } } } /* #[test] fn test_enumerate() { enumerate(["0", "1", "2"]) {|i,j| assert #fmt["%u",i] == j; } } #[test] fn test_map_and_to_vec() { let a = bind vec::iter([0, 1, 2], _); let b = bind map(a, {|i| 2*i}, _); let c = to_vec(b); assert c == [0, 2, 4]; } #[test] fn test_map_directly_on_vec() { let b = bind map([0, 1, 2], {|i| 2*i}, _); let c = to_vec(b); assert c == [0, 2, 4]; } #[test] fn test_filter_on_int_range() { fn is_even(&&i: int) -> bool { ret (i % 2) == 0; } let l = to_vec(bind filter(bind int::range(0, 10, _), is_even, _)); assert l == [0, 2, 4, 6, 8]; } #[test] fn test_filter_on_uint_range() { fn is_even(&&i: uint) -> bool { ret (i % 2u) == 0u; } let l = to_vec(bind filter(bind uint::range(0u, 10u, _), is_even, _)); assert l == [0u, 2u, 4u, 6u, 8u]; } #[test] fn test_filter_map() { fn negativate_the_evens(&&i: int) -> option { if i % 2 == 0 { some(-i) } else { none } } let l = to_vec(bind filter_map( bind int::range(0, 5, _), negativate_the_evens, _)); assert l == [0, -2, -4]; } #[test] fn test_flat_map_with_option() { fn if_even(&&i: int) -> option { if (i % 2) == 0 { some(i) } else { none } } let a = bind vec::iter([0, 1, 2], _); let b = bind flat_map(a, if_even, _); let c = to_vec(b); assert c == [0, 2]; } #[test] fn test_flat_map_with_list() { fn repeat(&&i: int) -> [int] { let mut r = []; int::range(0, i) {|_j| r += [i]; } r } let a = bind vec::iter([0, 1, 2, 3], _); let b = bind flat_map(a, repeat, _); let c = to_vec(b); #debug["c = %?", c]; assert c == [1, 2, 2, 3, 3, 3]; } #[test] fn test_repeat() { let mut c = [], i = 0u; repeat(5u) {|| c += [(i * i)]; i += 1u; }; #debug["c = %?", c]; assert c == [0u, 1u, 4u, 9u, 16u]; } #[test] fn test_min() { assert min([5, 4, 1, 2, 3]) == 1; } #[test] #[should_fail] #[ignore(cfg(windows))] fn test_min_empty() { min::([]); } #[test] fn test_max() { assert max([1, 2, 4, 2, 3]) == 4; } #[test] #[should_fail] #[ignore(cfg(windows))] fn test_max_empty() { max::([]); } #[test] fn test_reversed() { assert to_vec(bind reversed([1, 2, 3], _)) == [3, 2, 1]; } #[test] fn test_count() { assert count([1, 2, 1, 2, 1], 1) == 3u; } #[test] fn test_foldr() { fn sub(&&a: int, &&b: int) -> int { a - b } let sum = foldr([1, 2, 3, 4], 0, sub); assert sum == -2; } */