Skip to content

Commit 226fd87

Browse files
committed
Make a bunch more of the iteration functions/methods marked pure. Closes #3253.
1 parent 0f0a977 commit 226fd87

File tree

10 files changed

+138
-112
lines changed

10 files changed

+138
-112
lines changed

src/libcore/at_vec.rs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import ptr::addr_of;
44

55
export init_op;
66
export capacity;
7-
export build_sized, build;
7+
export build_sized, build, build_sized_opt;
88
export map;
99
export from_fn, from_elem;
1010
export unsafe;
@@ -78,6 +78,24 @@ pure fn build<A>(builder: fn(push: pure fn(+A))) -> @[A] {
7878
build_sized(4, builder)
7979
}
8080

81+
/**
82+
* Builds a vector by calling a provided function with an argument
83+
* function that pushes an element to the back of a vector.
84+
* This version takes an initial size for the vector.
85+
*
86+
* # Arguments
87+
*
88+
* * size - An option, maybe containing initial size of the vector to reserve
89+
* * builder - A function that will construct the vector. It recieves
90+
* as an argument a function that will push an element
91+
* onto the vector being constructed.
92+
*/
93+
#[inline(always)]
94+
pure fn build_sized_opt<A>(size: option<uint>,
95+
builder: fn(push: pure fn(+A))) -> @[A] {
96+
build_sized(size.get_default(4), builder)
97+
}
98+
8199
// Appending
82100
#[inline(always)]
83101
pure fn append<T: copy>(lhs: @[T], rhs: &[const T]) -> @[T] {

src/libcore/core.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import Path = path::Path;
88
import tuple::{TupleOps, ExtendedTupleOps};
99
import str::{StrSlice, UniqueStr};
1010
import vec::{ConstVector, CopyableVector, ImmutableVector};
11-
import vec::{ImmutableCopyableVector, IterTraitExtensions};
11+
import vec::{ImmutableCopyableVector};
1212
import iter::{BaseIter, ExtendedIter, CopyableIter, Times, TimesIx};
1313
import num::Num;
1414
import ptr::Ptr;

src/libcore/int-template.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ impl T: iter::Times {
9595
will execute the given function exactly x times. If we assume that \
9696
`x` is an int, this is functionally equivalent to \
9797
`for int::range(0, x) |_i| { /* anything */ }`."]
98-
fn times(it: fn() -> bool) {
98+
pure fn times(it: fn() -> bool) {
9999
if self < 0 {
100100
fail fmt!{"The .times method expects a nonnegative number, \
101101
but found %?", self};
@@ -111,7 +111,7 @@ impl T: iter::Times {
111111
impl T: iter::TimesIx {
112112
#[inline(always)]
113113
/// Like `times`, but provides an index
114-
fn timesi(it: fn(uint) -> bool) {
114+
pure fn timesi(it: fn(uint) -> bool) {
115115
let slf = self as uint;
116116
if slf < 0u {
117117
fail fmt!{"The .timesi method expects a nonnegative number, \

src/libcore/iter-trait.rs

Lines changed: 17 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -6,43 +6,39 @@ import inst::{IMPL_T, EACH, SIZE_HINT};
66
export extensions;
77

88
impl<A> IMPL_T<A>: iter::BaseIter<A> {
9-
fn each(blk: fn(A) -> bool) { EACH(self, blk) }
10-
fn size_hint() -> option<uint> { SIZE_HINT(self) }
9+
pure fn each(blk: fn(A) -> bool) { EACH(self, blk) }
10+
pure fn size_hint() -> option<uint> { SIZE_HINT(self) }
1111
}
1212

1313
impl<A> IMPL_T<A>: iter::ExtendedIter<A> {
14-
fn eachi(blk: fn(uint, A) -> bool) { iter::eachi(self, blk) }
15-
fn all(blk: fn(A) -> bool) -> bool { iter::all(self, blk) }
16-
fn any(blk: fn(A) -> bool) -> bool { iter::any(self, blk) }
17-
fn foldl<B>(+b0: B, blk: fn(B, A) -> B) -> B {
14+
pure fn eachi(blk: fn(uint, A) -> bool) { iter::eachi(self, blk) }
15+
pure fn all(blk: fn(A) -> bool) -> bool { iter::all(self, blk) }
16+
pure fn any(blk: fn(A) -> bool) -> bool { iter::any(self, blk) }
17+
pure fn foldl<B>(+b0: B, blk: fn(B, A) -> B) -> B {
1818
iter::foldl(self, b0, blk)
1919
}
20-
fn contains(x: A) -> bool { iter::contains(self, x) }
21-
fn count(x: A) -> uint { iter::count(self, x) }
22-
fn position(f: fn(A) -> bool) -> option<uint> {
20+
pure fn contains(x: A) -> bool { iter::contains(self, x) }
21+
pure fn count(x: A) -> uint { iter::count(self, x) }
22+
pure fn position(f: fn(A) -> bool) -> option<uint> {
2323
iter::position(self, f)
2424
}
2525
}
2626

2727
impl<A: copy> IMPL_T<A>: iter::CopyableIter<A> {
28-
fn filter_to_vec(pred: fn(A) -> bool) -> ~[A] {
28+
pure fn filter_to_vec(pred: fn(A) -> bool) -> ~[A] {
2929
iter::filter_to_vec(self, pred)
3030
}
31-
fn map_to_vec<B>(op: fn(A) -> B) -> ~[B] { iter::map_to_vec(self, op) }
32-
fn to_vec() -> ~[A] { iter::to_vec(self) }
31+
pure fn map_to_vec<B>(op: fn(A) -> B) -> ~[B] {
32+
iter::map_to_vec(self, op)
33+
}
34+
pure fn to_vec() -> ~[A] { iter::to_vec(self) }
3335

3436
// FIXME--bug in resolve prevents this from working (#2611)
3537
// fn flat_map_to_vec<B:copy,IB:base_iter<B>>(op: fn(A) -> IB) -> ~[B] {
3638
// iter::flat_map_to_vec(self, op)
3739
// }
3840

39-
fn min() -> A { iter::min(self) }
40-
fn max() -> A { iter::max(self) }
41-
42-
fn find(p: fn(A) -> bool) -> option<A> {
43-
for self.each |i| {
44-
if p(i) { return some(i) }
45-
}
46-
return none;
47-
}
41+
pure fn min() -> A { iter::min(self) }
42+
pure fn max() -> A { iter::max(self) }
43+
pure fn find(p: fn(A) -> bool) -> option<A> { iter::find(self, p) }
4844
}

src/libcore/iter-trait/dlist.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,6 @@ pure fn EACH<A>(self: IMPL_T<A>, f: fn(A) -> bool) {
2929
}
3030
}
3131

32-
fn SIZE_HINT<A>(self: IMPL_T<A>) -> option<uint> {
32+
pure fn SIZE_HINT<A>(self: IMPL_T<A>) -> option<uint> {
3333
some(self.len())
3434
}

src/libcore/iter-trait/dvec.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@ type IMPL_T<A> = dvec::DVec<A>;
66
*
77
* Attempts to access this dvec during iteration will fail.
88
*/
9-
fn EACH<A>(self: IMPL_T<A>, f: fn(A) -> bool) {
10-
self.swap(|v| { vec::each(v, f); v })
9+
pure fn EACH<A>(self: IMPL_T<A>, f: fn(A) -> bool) {
10+
unsafe { self.swap(|v| { vec::each(v, f); v }) }
1111
}
1212

13-
fn SIZE_HINT<A>(self: IMPL_T<A>) -> option<uint> {
13+
pure fn SIZE_HINT<A>(self: IMPL_T<A>) -> option<uint> {
1414
some(self.len())
1515
}

src/libcore/iter-trait/option.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ pure fn EACH<A>(self: IMPL_T<A>, f: fn(A) -> bool) {
77
}
88
}
99

10-
fn SIZE_HINT<A>(self: IMPL_T<A>) -> option<uint> {
10+
pure fn SIZE_HINT<A>(self: IMPL_T<A>) -> option<uint> {
1111
match self {
1212
none => some(0u),
1313
some(_) => some(1u)

src/libcore/iter.rs

Lines changed: 53 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,107 +1,106 @@
11
trait BaseIter<A> {
2-
fn each(blk: fn(A) -> bool);
3-
fn size_hint() -> option<uint>;
2+
pure fn each(blk: fn(A) -> bool);
3+
pure fn size_hint() -> option<uint>;
44
}
55

66
trait ExtendedIter<A> {
7-
fn eachi(blk: fn(uint, A) -> bool);
8-
fn all(blk: fn(A) -> bool) -> bool;
9-
fn any(blk: fn(A) -> bool) -> bool;
10-
fn foldl<B>(+b0: B, blk: fn(B, A) -> B) -> B;
11-
fn contains(x: A) -> bool;
12-
fn count(x: A) -> uint;
13-
fn position(f: fn(A) -> bool) -> option<uint>;
7+
pure fn eachi(blk: fn(uint, A) -> bool);
8+
pure fn all(blk: fn(A) -> bool) -> bool;
9+
pure fn any(blk: fn(A) -> bool) -> bool;
10+
pure fn foldl<B>(+b0: B, blk: fn(B, A) -> B) -> B;
11+
pure fn contains(x: A) -> bool;
12+
pure fn count(x: A) -> uint;
13+
pure fn position(f: fn(A) -> bool) -> option<uint>;
1414
}
1515

1616
trait Times {
17-
fn times(it: fn() -> bool);
17+
pure fn times(it: fn() -> bool);
1818
}
1919
trait TimesIx{
20-
fn timesi(it: fn(uint) -> bool);
20+
pure fn timesi(it: fn(uint) -> bool);
2121
}
2222

2323
trait CopyableIter<A:copy> {
24-
fn filter_to_vec(pred: fn(A) -> bool) -> ~[A];
25-
fn map_to_vec<B>(op: fn(A) -> B) -> ~[B];
26-
fn to_vec() -> ~[A];
27-
fn min() -> A;
28-
fn max() -> A;
29-
fn find(p: fn(A) -> bool) -> option<A>;
24+
pure fn filter_to_vec(pred: fn(A) -> bool) -> ~[A];
25+
pure fn map_to_vec<B>(op: fn(A) -> B) -> ~[B];
26+
pure fn to_vec() -> ~[A];
27+
pure fn min() -> A;
28+
pure fn max() -> A;
29+
pure fn find(p: fn(A) -> bool) -> option<A>;
3030
}
3131

32-
fn eachi<A,IA:BaseIter<A>>(self: IA, blk: fn(uint, A) -> bool) {
32+
pure fn eachi<A,IA:BaseIter<A>>(self: IA, blk: fn(uint, A) -> bool) {
3333
let mut i = 0u;
3434
for self.each |a| {
3535
if !blk(i, a) { break; }
3636
i += 1u;
3737
}
3838
}
3939

40-
fn all<A,IA:BaseIter<A>>(self: IA, blk: fn(A) -> bool) -> bool {
40+
pure fn all<A,IA:BaseIter<A>>(self: IA, blk: fn(A) -> bool) -> bool {
4141
for self.each |a| {
4242
if !blk(a) { return false; }
4343
}
4444
return true;
4545
}
4646

47-
fn any<A,IA:BaseIter<A>>(self: IA, blk: fn(A) -> bool) -> bool {
47+
pure fn any<A,IA:BaseIter<A>>(self: IA, blk: fn(A) -> bool) -> bool {
4848
for self.each |a| {
4949
if blk(a) { return true; }
5050
}
5151
return false;
5252
}
5353

54-
fn filter_to_vec<A:copy,IA:BaseIter<A>>(self: IA,
54+
pure fn filter_to_vec<A:copy,IA:BaseIter<A>>(self: IA,
5555
prd: fn(A) -> bool) -> ~[A] {
56-
let mut result = ~[];
57-
self.size_hint().iter(|hint| vec::reserve(result, hint));
58-
for self.each |a| {
59-
if prd(a) { vec::push(result, a); }
56+
do vec::build_sized_opt(self.size_hint()) |push| {
57+
for self.each |a| {
58+
if prd(a) { push(a); }
59+
}
6060
}
61-
return result;
6261
}
6362

64-
fn map_to_vec<A:copy,B,IA:BaseIter<A>>(self: IA, op: fn(A) -> B) -> ~[B] {
65-
let mut result = ~[];
66-
self.size_hint().iter(|hint| vec::reserve(result, hint));
67-
for self.each |a| {
68-
vec::push(result, op(a));
63+
pure fn map_to_vec<A:copy,B,IA:BaseIter<A>>(self: IA, op: fn(A) -> B)
64+
-> ~[B] {
65+
do vec::build_sized_opt(self.size_hint()) |push| {
66+
for self.each |a| {
67+
push(op(a));
68+
}
6969
}
70-
return result;
7170
}
7271

73-
fn flat_map_to_vec<A:copy,B:copy,IA:BaseIter<A>,IB:BaseIter<B>>(
72+
pure fn flat_map_to_vec<A:copy,B:copy,IA:BaseIter<A>,IB:BaseIter<B>>(
7473
self: IA, op: fn(A) -> IB) -> ~[B] {
7574

76-
let mut result = ~[];
77-
for self.each |a| {
78-
for op(a).each |b| {
79-
vec::push(result, b);
75+
do vec::build |push| {
76+
for self.each |a| {
77+
for op(a).each |b| {
78+
push(b);
79+
}
8080
}
8181
}
82-
return result;
8382
}
8483

85-
fn foldl<A,B,IA:BaseIter<A>>(self: IA, +b0: B, blk: fn(B, A) -> B) -> B {
84+
pure fn foldl<A,B,IA:BaseIter<A>>(self: IA, +b0: B, blk: fn(B, A) -> B) -> B {
8685
let mut b <- b0;
8786
for self.each |a| {
8887
b = blk(b, a);
8988
}
9089
return b;
9190
}
9291

93-
fn to_vec<A:copy,IA:BaseIter<A>>(self: IA) -> ~[A] {
92+
pure fn to_vec<A:copy,IA:BaseIter<A>>(self: IA) -> ~[A] {
9493
foldl::<A,~[A],IA>(self, ~[], |r, a| vec::append(r, ~[a]))
9594
}
9695

97-
fn contains<A,IA:BaseIter<A>>(self: IA, x: A) -> bool {
96+
pure fn contains<A,IA:BaseIter<A>>(self: IA, x: A) -> bool {
9897
for self.each |a| {
9998
if a == x { return true; }
10099
}
101100
return false;
102101
}
103102

104-
fn count<A,IA:BaseIter<A>>(self: IA, x: A) -> uint {
103+
pure fn count<A,IA:BaseIter<A>>(self: IA, x: A) -> uint {
105104
do foldl(self, 0u) |count, value| {
106105
if value == x {
107106
count + 1u
@@ -111,7 +110,7 @@ fn count<A,IA:BaseIter<A>>(self: IA, x: A) -> uint {
111110
}
112111
}
113112

114-
fn position<A,IA:BaseIter<A>>(self: IA, f: fn(A) -> bool)
113+
pure fn position<A,IA:BaseIter<A>>(self: IA, f: fn(A) -> bool)
115114
-> option<uint> {
116115
let mut i = 0;
117116
for self.each |a| {
@@ -125,15 +124,15 @@ fn position<A,IA:BaseIter<A>>(self: IA, f: fn(A) -> bool)
125124
// iter interface, such as would provide "reach" in addition to "each". as is,
126125
// it would have to be implemented with foldr, which is too inefficient.
127126

128-
fn repeat(times: uint, blk: fn() -> bool) {
127+
pure fn repeat(times: uint, blk: fn() -> bool) {
129128
let mut i = 0u;
130129
while i < times {
131130
if !blk() { break }
132131
i += 1u;
133132
}
134133
}
135134

136-
fn min<A:copy,IA:BaseIter<A>>(self: IA) -> A {
135+
pure fn min<A:copy,IA:BaseIter<A>>(self: IA) -> A {
137136
match do foldl::<A,option<A>,IA>(self, none) |a, b| {
138137
match a {
139138
some(a_) if a_ < b => {
@@ -149,7 +148,7 @@ fn min<A:copy,IA:BaseIter<A>>(self: IA) -> A {
149148
}
150149
}
151150

152-
fn max<A:copy,IA:BaseIter<A>>(self: IA) -> A {
151+
pure fn max<A:copy,IA:BaseIter<A>>(self: IA) -> A {
153152
match do foldl::<A,option<A>,IA>(self, none) |a, b| {
154153
match a {
155154
some(a_) if a_ > b => {
@@ -165,6 +164,14 @@ fn max<A:copy,IA:BaseIter<A>>(self: IA) -> A {
165164
}
166165
}
167166

167+
pure fn find<A: copy,IA:BaseIter<A>>(self: IA,
168+
p: fn(A) -> bool) -> option<A> {
169+
for self.each |i| {
170+
if p(i) { return some(i) }
171+
}
172+
return none;
173+
}
174+
168175
/*
169176
#[test]
170177
fn test_enumerate() {

src/libcore/uint-template.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ impl T: iter::Times {
8787
will execute the given function exactly x times. If we assume that \
8888
`x` is an int, this is functionally equivalent to \
8989
`for int::range(0, x) |_i| { /* anything */ }`."]
90-
fn times(it: fn() -> bool) {
90+
pure fn times(it: fn() -> bool) {
9191
let mut i = self;
9292
while i > 0 {
9393
if !it() { break }
@@ -99,7 +99,7 @@ impl T: iter::Times {
9999
impl T: iter::TimesIx {
100100
#[inline(always)]
101101
/// Like `times`, but with an index, `eachi`-style.
102-
fn timesi(it: fn(uint) -> bool) {
102+
pure fn timesi(it: fn(uint) -> bool) {
103103
let slf = self as uint;
104104
let mut i = 0u;
105105
while i < slf {

0 commit comments

Comments
 (0)