Skip to content

Commit e348567

Browse files
committed
new, simpler approach to the iter library
1 parent 5eca3c2 commit e348567

22 files changed

+320
-160
lines changed

src/libcore/core.rc

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@ export extfmt;
4242
export tuple;
4343
export to_str;
4444

45+
// NDM seems to be necessary for resolve to work
46+
export vec_iter, option_iter;
47+
4548
// FIXME: This creates some APIs that I do not want to commit to. It is
4649
// currently exported for the uv code in std, but when that code moves into
4750
// core this should become unexported
@@ -144,16 +147,25 @@ mod f64;
144147
mod str;
145148
mod ptr;
146149
mod vec;
150+
#[path="iter-trait"]
151+
mod vec_iter {
152+
#[path = "vec.rs"]
153+
mod inst;
154+
}
147155
mod bool;
148156
mod tuple;
149157

150-
151158
// Ubiquitous-utility-type modules
152159

153160
mod either;
154161
mod iter;
155162
mod logging;
156163
mod option;
164+
#[path="iter-trait"]
165+
mod option_iter {
166+
#[path = "option.rs"]
167+
mod inst;
168+
}
157169
mod result;
158170
mod to_str;
159171

@@ -195,5 +207,4 @@ mod cmath;
195207
// indent-tabs-mode: nil
196208
// c-basic-offset: 4
197209
// buffer-file-coding-system: utf-8-unix
198-
// compile-command: "make -k -C .. 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
199210
// End:

src/libcore/core.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@ import option = option::option;
77
import path = path::path;
88
import str::extensions;
99
import vec::extensions;
10+
import vec_iter::extensions;
1011
import option::extensions;
12+
import option_iter::extensions;
1113
import ptr::extensions;
1214

1315
export path, option, some, none, unreachable;

src/libcore/iter-trait.rs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// This makes use of a clever hack that brson came up with to
2+
// workaround our lack of traits and lack of macros. See core.{rc,rs} for
3+
// how this file is used.
4+
5+
import inst::{IMPL_T, EACH, SIZE_HINT};
6+
export extensions;
7+
8+
impl extensions<A> of iter::base_iter<A> for IMPL_T<A> {
9+
fn each(blk: fn(A) -> bool) { EACH(self, blk) }
10+
fn size_hint() -> option<uint> { SIZE_HINT(self) }
11+
fn eachi(blk: fn(uint, A) -> bool) { iter::eachi(self, blk) }
12+
fn all(blk: fn(A) -> bool) -> bool { iter::all(self, blk) }
13+
fn any(blk: fn(A) -> bool) -> bool { iter::any(self, blk) }
14+
fn foldl<B>(+b0: B, blk: fn(B, A) -> B) -> B {
15+
iter::foldl(self, b0, blk)
16+
}
17+
fn contains(x: A) -> bool { iter::contains(self, x) }
18+
fn count(x: A) -> uint { iter::count(self, x) }
19+
}
20+
21+
impl extensions<A:copy> for IMPL_T<A> {
22+
fn filter_to_vec(pred: fn(A) -> bool) -> [A] {
23+
iter::filter_to_vec(self, pred)
24+
}
25+
fn map_to_vec<B>(op: fn(A) -> B) -> [B] { iter::map_to_vec(self, op) }
26+
fn to_vec() -> [A] { iter::to_vec(self) }
27+
28+
// FIXME--bug in resolve prevents this from working
29+
// fn flat_map_to_vec<B:copy,IB:base_iter<B>>(op: fn(A) -> IB) -> [B] {
30+
// iter::flat_map_to_vec(self, op)
31+
// }
32+
33+
fn min() -> A { iter::min(self) }
34+
fn max() -> A { iter::max(self) }
35+
}

src/libcore/iter-trait/option.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
type IMPL_T<A> = option<A>;
2+
3+
fn EACH<A>(self: IMPL_T<A>, f: fn(A) -> bool) {
4+
alt self {
5+
none { }
6+
some(a) { f(a); }
7+
}
8+
}
9+
10+
fn SIZE_HINT<A>(self: IMPL_T<A>) -> option<uint> {
11+
alt self {
12+
none { some(0u) }
13+
some(_) { some(1u) }
14+
}
15+
}

src/libcore/iter-trait/vec.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
type IMPL_T<A> = [const A];
2+
3+
fn EACH<A>(self: IMPL_T<A>, f: fn(A) -> bool) {
4+
vec::each(self, f)
5+
}
6+
7+
fn SIZE_HINT<A>(self: IMPL_T<A>) -> option<uint> {
8+
some(vec::len(self))
9+
}

src/libcore/iter.rs

Lines changed: 51 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -1,115 +1,81 @@
1-
iface iterable<A> {
2-
fn iter(blk: fn(A));
1+
iface base_iter<A> {
2+
fn each(blk: fn(A) -> bool);
3+
fn size_hint() -> option<uint>;
34
}
45

5-
impl<A> of iterable<A> for fn@(fn(A)) {
6-
fn iter(blk: fn(A)) {
7-
self(blk);
8-
}
9-
}
10-
11-
// accomodate the fact that int/uint are passed by value by default:
12-
impl of iterable<int> for fn@(fn(int)) {
13-
fn iter(blk: fn(&&int)) {
14-
self {|i| blk(i)}
15-
}
16-
}
17-
18-
impl of iterable<uint> for fn@(fn(uint)) {
19-
fn iter(blk: fn(&&uint)) {
20-
self {|i| blk(i)}
21-
}
22-
}
23-
24-
impl<A> of iterable<A> for [A] {
25-
fn iter(blk: fn(A)) {
26-
vec::iter(self, blk)
27-
}
28-
}
29-
30-
impl<A> of iterable<A> for option<A> {
31-
fn iter(blk: fn(A)) {
32-
option::iter(self, blk)
33-
}
34-
}
35-
36-
impl of iterable<char> for str {
37-
fn iter(blk: fn(&&char)) {
38-
str::chars_iter(self) { |ch| blk(ch) }
39-
}
40-
}
41-
42-
fn enumerate<A,IA:iterable<A>>(self: IA, blk: fn(uint, A)) {
6+
fn eachi<A,IA:base_iter<A>>(self: IA, blk: fn(uint, A) -> bool) {
437
let mut i = 0u;
44-
self.iter {|a|
45-
blk(i, a);
8+
for self.each {|a|
9+
if !blk(i, a) { break; }
4610
i += 1u;
4711
}
4812
}
4913

50-
// Here: we have to use fn@ for predicates and map functions, because
51-
// we will be binding them up into a closure. Disappointing. A true
52-
// region type system might be able to do better than this.
53-
54-
fn filter<A,IA:iterable<A>>(self: IA, prd: fn@(A) -> bool, blk: fn(A)) {
55-
self.iter {|a|
56-
if prd(a) { blk(a) }
14+
fn all<A,IA:base_iter<A>>(self: IA, blk: fn(A) -> bool) -> bool {
15+
for self.each {|a|
16+
if !blk(a) { ret false; }
5717
}
18+
ret true;
5819
}
5920

60-
fn filter_map<A,B,IA:iterable<A>>(self: IA, cnv: fn@(A) -> option<B>,
61-
blk: fn(B)) {
62-
self.iter {|a|
63-
alt cnv(a) {
64-
some(b) { blk(b) }
65-
none { }
66-
}
21+
fn any<A,IA:base_iter<A>>(self: IA, blk: fn(A) -> bool) -> bool {
22+
for self.each {|a|
23+
if blk(a) { ret true; }
6724
}
25+
ret false;
6826
}
6927

70-
fn map<A,B,IA:iterable<A>>(self: IA, cnv: fn@(A) -> B, blk: fn(B)) {
71-
self.iter {|a|
72-
let b = cnv(a);
73-
blk(b);
28+
fn filter_to_vec<A:copy,IA:base_iter<A>>(self: IA,
29+
prd: fn(A) -> bool) -> [A] {
30+
let mut result = [];
31+
self.size_hint().iter {|hint| vec::reserve(result, hint); }
32+
for self.each {|a|
33+
if prd(a) { vec::push(result, a); }
7434
}
35+
ret result;
7536
}
7637

77-
fn flat_map<A,B,IA:iterable<A>,IB:iterable<B>>(
78-
self: IA, cnv: fn@(A) -> IB, blk: fn(B)) {
79-
self.iter {|a|
80-
cnv(a).iter(blk)
38+
fn map_to_vec<A:copy,B,IA:base_iter<A>>(self: IA, op: fn(A) -> B) -> [B] {
39+
let mut result = [];
40+
self.size_hint().iter {|hint| vec::reserve(result, hint); }
41+
for self.each {|a|
42+
vec::push(result, op(a));
8143
}
44+
ret result;
8245
}
8346

84-
fn foldl<A,B,IA:iterable<A>>(self: IA, +b0: B, blk: fn(B, A) -> B) -> B {
85-
let mut b <- b0;
86-
self.iter {|a|
87-
b <- blk(b, a);
47+
fn flat_map_to_vec<A:copy,B:copy,IA:base_iter<A>,IB:base_iter<B>>(
48+
self: IA, op: fn(A) -> IB) -> [B] {
49+
50+
let mut result = [];
51+
for self.each {|a|
52+
for op(a).each {|b|
53+
vec::push(result, b);
54+
}
8855
}
89-
ret b;
56+
ret result;
9057
}
9158

92-
fn foldr<A:copy,B,IA:iterable<A>>(
93-
self: IA, +b0: B, blk: fn(A, B) -> B) -> B {
94-
59+
fn foldl<A,B,IA:base_iter<A>>(self: IA, +b0: B, blk: fn(B, A) -> B) -> B {
9560
let mut b <- b0;
96-
reversed(self) {|a|
97-
b <- blk(a, b);
61+
for self.each {|a|
62+
b = blk(b, a);
9863
}
9964
ret b;
10065
}
10166

102-
fn to_vec<A:copy,IA:iterable<A>>(self: IA) -> [A] {
67+
fn to_vec<A:copy,IA:base_iter<A>>(self: IA) -> [A] {
10368
foldl::<A,[A],IA>(self, [], {|r, a| r + [a]})
10469
}
10570

106-
// FIXME: This could be made more efficient with an riterable interface
107-
// #2005
108-
fn reversed<A:copy,IA:iterable<A>>(self: IA, blk: fn(A)) {
109-
vec::riter(to_vec(self), blk)
71+
fn contains<A,IA:base_iter<A>>(self: IA, x: A) -> bool {
72+
for self.each {|a|
73+
if a == x { ret true; }
74+
}
75+
ret false;
11076
}
11177

112-
fn count<A,IA:iterable<A>>(self: IA, x: A) -> uint {
78+
fn count<A,IA:base_iter<A>>(self: IA, x: A) -> uint {
11379
foldl(self, 0u) {|count, value|
11480
if value == x {
11581
count + 1u
@@ -127,7 +93,7 @@ fn repeat(times: uint, blk: fn()) {
12793
}
12894
}
12995

130-
fn min<A:copy,IA:iterable<A>>(self: IA) -> A {
96+
fn min<A:copy,IA:base_iter<A>>(self: IA) -> A {
13197
alt foldl::<A,option<A>,IA>(self, none) {|a, b|
13298
alt a {
13399
some(a_) if a_ < b {
@@ -143,7 +109,7 @@ fn min<A:copy,IA:iterable<A>>(self: IA) -> A {
143109
}
144110
}
145111

146-
fn max<A:copy,IA:iterable<A>>(self: IA) -> A {
112+
fn max<A:copy,IA:base_iter<A>>(self: IA) -> A {
147113
alt foldl::<A,option<A>,IA>(self, none) {|a, b|
148114
alt a {
149115
some(a_) if a_ > b {
@@ -159,6 +125,7 @@ fn max<A:copy,IA:iterable<A>>(self: IA) -> A {
159125
}
160126
}
161127

128+
/*
162129
#[test]
163130
fn test_enumerate() {
164131
enumerate(["0", "1", "2"]) {|i,j|
@@ -296,4 +263,5 @@ fn test_foldr() {
296263
}
297264
let sum = foldr([1, 2, 3, 4], 0, sub);
298265
assert sum == -2;
299-
}
266+
}
267+
*/

src/libcore/option.rs

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -101,23 +101,6 @@ impl extensions<T:copy> for option<T> {
101101
#[doc = "Performs an operation on the contained value or does nothing"]
102102
fn iter(f: fn(T)) { iter(self, f) }
103103

104-
#[doc = "Converts `none` to a zero-element list and `some` to a \
105-
one-element list."]
106-
fn to_vec() -> [T] {
107-
alt self {
108-
some(t) { [t] }
109-
none { [] }
110-
}
111-
}
112-
113-
#[doc = "Performs an operation on the contained value or does nothing"]
114-
fn each(f: fn(T) -> bool) {
115-
alt self {
116-
none { /* ok */ }
117-
some(e) { f(e); }
118-
}
119-
}
120-
121104
#[doc = "
122105
Gets the value out of an option
123106

0 commit comments

Comments
 (0)