rust/src/libcore/iter.rs

268 lines
5.4 KiB
Rust
Raw Normal View History

iface base_iter<A> {
fn each(blk: fn(A) -> bool);
fn size_hint() -> option<uint>;
}
fn eachi<A,IA:base_iter<A>>(self: IA, blk: fn(uint, A) -> bool) {
2012-03-06 22:48:40 -06:00
let mut i = 0u;
for self.each {|a|
if !blk(i, a) { break; }
i += 1u;
}
}
fn all<A,IA:base_iter<A>>(self: IA, blk: fn(A) -> bool) -> bool {
for self.each {|a|
if !blk(a) { ret false; }
}
ret true;
}
fn any<A,IA:base_iter<A>>(self: IA, blk: fn(A) -> bool) -> bool {
for self.each {|a|
if blk(a) { ret true; }
2012-02-13 00:30:58 -06:00
}
ret false;
2012-02-13 00:30:58 -06:00
}
fn filter_to_vec<A:copy,IA:base_iter<A>>(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<A:copy,B,IA:base_iter<A>>(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<A:copy,B:copy,IA:base_iter<A>,IB:base_iter<B>>(
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<A,B,IA:base_iter<A>>(self: IA, +b0: B, blk: fn(B, A) -> B) -> B {
2012-03-06 22:48:40 -06:00
let mut b <- b0;
for self.each {|a|
b = blk(b, a);
2012-02-12 04:57:50 -06:00
}
ret b;
}
fn to_vec<A:copy,IA:base_iter<A>>(self: IA) -> [A] {
foldl::<A,[A],IA>(self, [], {|r, a| r + [a]})
}
fn contains<A,IA:base_iter<A>>(self: IA, x: A) -> bool {
for self.each {|a|
if a == x { ret true; }
}
ret false;
2012-02-12 04:44:40 -06:00
}
fn count<A,IA:base_iter<A>>(self: IA, x: A) -> uint {
2012-02-12 04:50:37 -06:00
foldl(self, 0u) {|count, value|
if value == x {
count + 1u
} else {
count
}
}
}
fn repeat(times: uint, blk: fn()) {
2012-03-06 22:48:40 -06:00
let mut i = 0u;
while i < times {
blk();
i += 1u;
}
}
fn min<A:copy,IA:base_iter<A>>(self: IA) -> A {
alt foldl::<A,option<A>,IA>(self, none) {|a, b|
2012-02-12 04:36:40 -06:00
alt a {
some(a_) if a_ < b {
// FIXME: Not sure if this is successfully optimized to a move
// #2005
a
}
_ { some(b) }
2012-02-12 04:36:40 -06:00
}
} {
some(val) { val }
none { fail "min called on empty iterator" }
}
}
fn max<A:copy,IA:base_iter<A>>(self: IA) -> A {
alt foldl::<A,option<A>,IA>(self, none) {|a, b|
2012-02-12 04:36:40 -06:00
alt a {
some(a_) if a_ > b {
// FIXME: Not sure if this is successfully optimized to a move
// #2005
a
}
_ { some(b) }
2012-02-12 04:36:40 -06:00
}
} {
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], _);
2012-03-22 22:06:01 -05:00
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() {
2012-03-22 22:06:01 -05:00
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];
}
2012-02-13 00:30:58 -06:00
#[test]
fn test_filter_map() {
fn negativate_the_evens(&&i: int) -> option<int> {
if i % 2 == 0 {
some(-i)
} else {
none
}
}
let l = to_vec(bind filter_map(
2012-02-13 00:30:58 -06:00
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<int> {
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];
}
2012-02-12 04:36:40 -06:00
#[test]
fn test_min() {
assert min([5, 4, 1, 2, 3]) == 1;
}
2012-02-12 04:36:40 -06:00
#[test]
#[should_fail]
#[ignore(cfg(target_os = "win32"))]
fn test_min_empty() {
min::<int, [int]>([]);
}
#[test]
fn test_max() {
assert max([1, 2, 4, 2, 3]) == 4;
}
#[test]
#[should_fail]
#[ignore(cfg(target_os = "win32"))]
fn test_max_empty() {
max::<int, [int]>([]);
}
2012-02-12 04:44:40 -06:00
#[test]
fn test_reversed() {
assert to_vec(bind reversed([1, 2, 3], _)) == [3, 2, 1];
2012-02-12 04:50:37 -06:00
}
#[test]
fn test_count() {
assert count([1, 2, 1, 2, 1], 1) == 3u;
2012-02-12 04:57:50 -06:00
}
#[test]
fn test_foldr() {
fn sub(&&a: int, &&b: int) -> int {
2012-02-12 04:57:50 -06:00
a - b
}
let sum = foldr([1, 2, 3, 4], 0, sub);
assert sum == -2;
}
*/