2012-04-11 23:45:18 -05:00
|
|
|
iface base_iter<A> {
|
|
|
|
fn each(blk: fn(A) -> bool);
|
|
|
|
fn size_hint() -> option<uint>;
|
2012-01-31 20:52:20 -06:00
|
|
|
}
|
|
|
|
|
2012-04-11 23:45:18 -05:00
|
|
|
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;
|
2012-06-30 18:19:07 -05:00
|
|
|
for self.each |a| {
|
2012-04-11 23:45:18 -05:00
|
|
|
if !blk(i, a) { break; }
|
2012-01-31 20:52:20 -06:00
|
|
|
i += 1u;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-04-11 23:45:18 -05:00
|
|
|
fn all<A,IA:base_iter<A>>(self: IA, blk: fn(A) -> bool) -> bool {
|
2012-06-30 18:19:07 -05:00
|
|
|
for self.each |a| {
|
2012-04-11 23:45:18 -05:00
|
|
|
if !blk(a) { ret false; }
|
2012-01-31 20:52:20 -06:00
|
|
|
}
|
2012-04-11 23:45:18 -05:00
|
|
|
ret true;
|
2012-01-31 20:52:20 -06:00
|
|
|
}
|
|
|
|
|
2012-04-11 23:45:18 -05:00
|
|
|
fn any<A,IA:base_iter<A>>(self: IA, blk: fn(A) -> bool) -> bool {
|
2012-06-30 18:19:07 -05:00
|
|
|
for self.each |a| {
|
2012-04-11 23:45:18 -05:00
|
|
|
if blk(a) { ret true; }
|
2012-02-13 00:30:58 -06:00
|
|
|
}
|
2012-04-11 23:45:18 -05:00
|
|
|
ret false;
|
2012-02-13 00:30:58 -06:00
|
|
|
}
|
|
|
|
|
2012-04-11 23:45:18 -05:00
|
|
|
fn filter_to_vec<A:copy,IA:base_iter<A>>(self: IA,
|
2012-06-29 18:26:56 -05:00
|
|
|
prd: fn(A) -> bool) -> ~[A] {
|
|
|
|
let mut result = ~[];
|
2012-06-30 18:19:07 -05:00
|
|
|
self.size_hint().iter(|hint| vec::reserve(result, hint));
|
|
|
|
for self.each |a| {
|
2012-04-11 23:45:18 -05:00
|
|
|
if prd(a) { vec::push(result, a); }
|
2012-01-31 20:52:20 -06:00
|
|
|
}
|
2012-04-11 23:45:18 -05:00
|
|
|
ret result;
|
2012-01-31 20:52:20 -06:00
|
|
|
}
|
|
|
|
|
2012-06-29 18:26:56 -05:00
|
|
|
fn map_to_vec<A:copy,B,IA:base_iter<A>>(self: IA, op: fn(A) -> B) -> ~[B] {
|
|
|
|
let mut result = ~[];
|
2012-06-30 18:19:07 -05:00
|
|
|
self.size_hint().iter(|hint| vec::reserve(result, hint));
|
|
|
|
for self.each |a| {
|
2012-04-11 23:45:18 -05:00
|
|
|
vec::push(result, op(a));
|
2012-01-31 20:52:20 -06:00
|
|
|
}
|
2012-04-11 23:45:18 -05:00
|
|
|
ret result;
|
2012-01-31 20:52:20 -06:00
|
|
|
}
|
|
|
|
|
2012-04-11 23:45:18 -05:00
|
|
|
fn flat_map_to_vec<A:copy,B:copy,IA:base_iter<A>,IB:base_iter<B>>(
|
2012-06-29 18:26:56 -05:00
|
|
|
self: IA, op: fn(A) -> IB) -> ~[B] {
|
2012-04-11 23:45:18 -05:00
|
|
|
|
2012-06-29 18:26:56 -05:00
|
|
|
let mut result = ~[];
|
2012-06-30 18:19:07 -05:00
|
|
|
for self.each |a| {
|
|
|
|
for op(a).each |b| {
|
2012-04-11 23:45:18 -05:00
|
|
|
vec::push(result, b);
|
|
|
|
}
|
2012-01-31 20:52:20 -06:00
|
|
|
}
|
2012-04-11 23:45:18 -05:00
|
|
|
ret result;
|
2012-01-31 20:52:20 -06:00
|
|
|
}
|
|
|
|
|
2012-04-11 23:45:18 -05:00
|
|
|
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;
|
2012-06-30 18:19:07 -05:00
|
|
|
for self.each |a| {
|
2012-04-11 23:45:18 -05:00
|
|
|
b = blk(b, a);
|
2012-02-12 04:57:50 -06:00
|
|
|
}
|
|
|
|
ret b;
|
|
|
|
}
|
|
|
|
|
2012-06-29 18:26:56 -05:00
|
|
|
fn to_vec<A:copy,IA:base_iter<A>>(self: IA) -> ~[A] {
|
2012-06-30 18:19:07 -05:00
|
|
|
foldl::<A,~[A],IA>(self, ~[], |r, a| vec::append(r, ~[a]))
|
2012-01-31 20:52:20 -06:00
|
|
|
}
|
|
|
|
|
2012-04-11 23:45:18 -05:00
|
|
|
fn contains<A,IA:base_iter<A>>(self: IA, x: A) -> bool {
|
2012-06-30 18:19:07 -05:00
|
|
|
for self.each |a| {
|
2012-04-11 23:45:18 -05:00
|
|
|
if a == x { ret true; }
|
|
|
|
}
|
|
|
|
ret false;
|
2012-02-12 04:44:40 -06:00
|
|
|
}
|
|
|
|
|
2012-04-11 23:45:18 -05:00
|
|
|
fn count<A,IA:base_iter<A>>(self: IA, x: A) -> uint {
|
2012-06-30 18:19:07 -05:00
|
|
|
do foldl(self, 0u) |count, value| {
|
2012-02-12 04:50:37 -06:00
|
|
|
if value == x {
|
|
|
|
count + 1u
|
|
|
|
} else {
|
|
|
|
count
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-06-25 17:04:00 -05:00
|
|
|
fn position<A,IA:base_iter<A>>(self: IA, f: fn(A) -> bool)
|
|
|
|
-> option<uint> {
|
|
|
|
let mut i = 0;
|
2012-06-30 18:19:07 -05:00
|
|
|
for self.each |a| {
|
2012-06-25 17:04:00 -05:00
|
|
|
if f(a) { ret some(i); }
|
|
|
|
i += 1;
|
|
|
|
}
|
|
|
|
ret none;
|
|
|
|
}
|
|
|
|
|
|
|
|
// note: 'rposition' would only make sense to provide with a bidirectional
|
|
|
|
// iter interface, such as would provide "reach" in addition to "each". as is,
|
|
|
|
// it would have to be implemented with foldr, which is too inefficient.
|
|
|
|
|
2012-07-03 18:46:57 -05:00
|
|
|
fn repeat(times: uint, blk: fn() -> bool) {
|
2012-03-06 22:48:40 -06:00
|
|
|
let mut i = 0u;
|
2012-01-31 20:52:20 -06:00
|
|
|
while i < times {
|
2012-07-03 18:46:57 -05:00
|
|
|
if !blk() { break }
|
2012-01-31 20:52:20 -06:00
|
|
|
i += 1u;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-04-11 23:45:18 -05:00
|
|
|
fn min<A:copy,IA:base_iter<A>>(self: IA) -> A {
|
2012-06-30 18:19:07 -05:00
|
|
|
alt do foldl::<A,option<A>,IA>(self, none) |a, b| {
|
2012-02-12 04:36:40 -06:00
|
|
|
alt a {
|
2012-02-12 05:04:33 -06:00
|
|
|
some(a_) if a_ < b {
|
2012-06-21 18:44:10 -05:00
|
|
|
// FIXME (#2005): Not sure if this is successfully optimized to
|
|
|
|
// a move
|
2012-02-12 05:04:33 -06:00
|
|
|
a
|
|
|
|
}
|
|
|
|
_ { some(b) }
|
2012-02-12 04:36:40 -06:00
|
|
|
}
|
|
|
|
} {
|
|
|
|
some(val) { val }
|
|
|
|
none { fail "min called on empty iterator" }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-04-11 23:45:18 -05:00
|
|
|
fn max<A:copy,IA:base_iter<A>>(self: IA) -> A {
|
2012-06-30 18:19:07 -05:00
|
|
|
alt do foldl::<A,option<A>,IA>(self, none) |a, b| {
|
2012-02-12 04:36:40 -06:00
|
|
|
alt a {
|
2012-02-12 05:04:33 -06:00
|
|
|
some(a_) if a_ > b {
|
2012-06-21 18:44:10 -05:00
|
|
|
// FIXME (#2005): Not sure if this is successfully optimized to
|
|
|
|
// a move.
|
2012-02-12 05:04:33 -06:00
|
|
|
a
|
|
|
|
}
|
|
|
|
_ { some(b) }
|
2012-02-12 04:36:40 -06:00
|
|
|
}
|
|
|
|
} {
|
|
|
|
some(val) { val }
|
|
|
|
none { fail "max called on empty iterator" }
|
|
|
|
}
|
|
|
|
}
|
2012-01-31 20:52:20 -06:00
|
|
|
|
2012-04-11 23:45:18 -05:00
|
|
|
/*
|
2012-01-31 20:52:20 -06:00
|
|
|
#[test]
|
|
|
|
fn test_enumerate() {
|
|
|
|
enumerate(["0", "1", "2"]) {|i,j|
|
|
|
|
assert #fmt["%u",i] == j;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2012-03-27 16:50:23 -05:00
|
|
|
fn test_map_and_to_vec() {
|
2012-06-29 18:26:56 -05:00
|
|
|
let a = bind vec::iter(~[0, 1, 2], _);
|
2012-03-22 22:06:01 -05:00
|
|
|
let b = bind map(a, {|i| 2*i}, _);
|
2012-03-27 16:50:23 -05:00
|
|
|
let c = to_vec(b);
|
2012-06-29 18:26:56 -05:00
|
|
|
assert c == ~[0, 2, 4];
|
2012-01-31 20:52:20 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_map_directly_on_vec() {
|
2012-06-29 18:26:56 -05:00
|
|
|
let b = bind map(~[0, 1, 2], {|i| 2*i}, _);
|
2012-03-27 16:50:23 -05:00
|
|
|
let c = to_vec(b);
|
2012-06-29 18:26:56 -05:00
|
|
|
assert c == ~[0, 2, 4];
|
2012-01-31 20:52:20 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_filter_on_int_range() {
|
|
|
|
fn is_even(&&i: int) -> bool {
|
|
|
|
ret (i % 2) == 0;
|
|
|
|
}
|
|
|
|
|
2012-03-27 16:50:23 -05:00
|
|
|
let l = to_vec(bind filter(bind int::range(0, 10, _), is_even, _));
|
2012-06-29 18:26:56 -05:00
|
|
|
assert l == ~[0, 2, 4, 6, 8];
|
2012-01-31 20:52:20 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_filter_on_uint_range() {
|
|
|
|
fn is_even(&&i: uint) -> bool {
|
|
|
|
ret (i % 2u) == 0u;
|
|
|
|
}
|
|
|
|
|
2012-03-27 16:50:23 -05:00
|
|
|
let l = to_vec(bind filter(bind uint::range(0u, 10u, _), is_even, _));
|
2012-06-29 18:26:56 -05:00
|
|
|
assert l == ~[0u, 2u, 4u, 6u, 8u];
|
2012-01-31 20:52:20 -06:00
|
|
|
}
|
|
|
|
|
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
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-03-27 16:50:23 -05:00
|
|
|
let l = to_vec(bind filter_map(
|
2012-02-13 00:30:58 -06:00
|
|
|
bind int::range(0, 5, _), negativate_the_evens, _));
|
2012-06-29 18:26:56 -05:00
|
|
|
assert l == ~[0, -2, -4];
|
2012-02-13 00:30:58 -06:00
|
|
|
}
|
|
|
|
|
2012-01-31 20:52:20 -06:00
|
|
|
#[test]
|
|
|
|
fn test_flat_map_with_option() {
|
|
|
|
fn if_even(&&i: int) -> option<int> {
|
|
|
|
if (i % 2) == 0 { some(i) }
|
|
|
|
else { none }
|
|
|
|
}
|
|
|
|
|
2012-06-29 18:26:56 -05:00
|
|
|
let a = bind vec::iter(~[0, 1, 2], _);
|
2012-01-31 20:52:20 -06:00
|
|
|
let b = bind flat_map(a, if_even, _);
|
2012-03-27 16:50:23 -05:00
|
|
|
let c = to_vec(b);
|
2012-06-29 18:26:56 -05:00
|
|
|
assert c == ~[0, 2];
|
2012-01-31 20:52:20 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_flat_map_with_list() {
|
2012-06-29 18:26:56 -05:00
|
|
|
fn repeat(&&i: int) -> ~[int] {
|
|
|
|
let mut r = ~[];
|
|
|
|
int::range(0, i) {|_j| r += ~[i]; }
|
2012-01-31 20:52:20 -06:00
|
|
|
r
|
|
|
|
}
|
|
|
|
|
2012-06-29 18:26:56 -05:00
|
|
|
let a = bind vec::iter(~[0, 1, 2, 3], _);
|
2012-01-31 20:52:20 -06:00
|
|
|
let b = bind flat_map(a, repeat, _);
|
2012-03-27 16:50:23 -05:00
|
|
|
let c = to_vec(b);
|
2012-01-31 20:52:20 -06:00
|
|
|
#debug["c = %?", c];
|
2012-06-29 18:26:56 -05:00
|
|
|
assert c == ~[1, 2, 2, 3, 3, 3];
|
2012-01-31 20:52:20 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_repeat() {
|
2012-06-29 18:26:56 -05:00
|
|
|
let mut c = ~[], i = 0u;
|
2012-01-31 20:52:20 -06:00
|
|
|
repeat(5u) {||
|
2012-06-29 18:26:56 -05:00
|
|
|
c += ~[(i * i)];
|
2012-01-31 20:52:20 -06:00
|
|
|
i += 1u;
|
|
|
|
};
|
|
|
|
#debug["c = %?", c];
|
2012-06-29 18:26:56 -05:00
|
|
|
assert c == ~[0u, 1u, 4u, 9u, 16u];
|
2012-01-31 20:52:20 -06:00
|
|
|
}
|
|
|
|
|
2012-02-12 04:36:40 -06:00
|
|
|
#[test]
|
|
|
|
fn test_min() {
|
2012-06-29 18:26:56 -05:00
|
|
|
assert min(~[5, 4, 1, 2, 3]) == 1;
|
2012-02-12 04:36:40 -06:00
|
|
|
}
|
2012-01-31 20:52:20 -06:00
|
|
|
|
2012-02-12 04:36:40 -06:00
|
|
|
#[test]
|
|
|
|
#[should_fail]
|
2012-06-07 23:38:25 -05:00
|
|
|
#[ignore(cfg(windows))]
|
2012-02-12 04:36:40 -06:00
|
|
|
fn test_min_empty() {
|
2012-06-29 18:26:56 -05:00
|
|
|
min::<int, ~[int]>(~[]);
|
2012-02-12 04:36:40 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_max() {
|
2012-06-29 18:26:56 -05:00
|
|
|
assert max(~[1, 2, 4, 2, 3]) == 4;
|
2012-02-12 04:36:40 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
#[should_fail]
|
2012-06-07 23:38:25 -05:00
|
|
|
#[ignore(cfg(windows))]
|
2012-02-12 04:36:40 -06:00
|
|
|
fn test_max_empty() {
|
2012-06-29 18:26:56 -05:00
|
|
|
max::<int, ~[int]>(~[]);
|
2012-02-12 04:36:40 -06:00
|
|
|
}
|
2012-02-12 04:44:40 -06:00
|
|
|
|
|
|
|
#[test]
|
2012-02-13 00:11:42 -06:00
|
|
|
fn test_reversed() {
|
2012-06-29 18:26:56 -05:00
|
|
|
assert to_vec(bind reversed(~[1, 2, 3], _)) == ~[3, 2, 1];
|
2012-02-12 04:50:37 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_count() {
|
2012-06-29 18:26:56 -05:00
|
|
|
assert count(~[1, 2, 1, 2, 1], 1) == 3u;
|
2012-02-12 04:57:50 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_foldr() {
|
2012-04-12 23:58:32 -05:00
|
|
|
fn sub(&&a: int, &&b: int) -> int {
|
2012-02-12 04:57:50 -06:00
|
|
|
a - b
|
|
|
|
}
|
2012-06-29 18:26:56 -05:00
|
|
|
let sum = foldr(~[1, 2, 3, 4], 0, sub);
|
2012-02-12 04:57:50 -06:00
|
|
|
assert sum == -2;
|
2012-04-11 23:45:18 -05:00
|
|
|
}
|
|
|
|
*/
|