Skip to content

Commit efd1438

Browse files
committed
auto merge of #7373 : thestinger/rust/iterator, r=huonw
2 parents 4967bd0 + e44e33d commit efd1438

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+259
-382
lines changed

doc/tutorial.md

Lines changed: 44 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1552,13 +1552,6 @@ fn each(v: &[int], op: &fn(v: &int)) {
15521552
}
15531553
~~~~
15541554

1555-
As an aside, the reason we pass in a *pointer* to an integer rather
1556-
than the integer itself is that this is how the actual `each()`
1557-
function for vectors works. `vec::each` though is a
1558-
[generic](#generics) function, so must be efficient to use for all
1559-
types. Passing the elements by pointer avoids copying potentially
1560-
large objects.
1561-
15621555
As a caller, if we use a closure to provide the final operator
15631556
argument, we can write it in a way that has a pleasant, block-like
15641557
structure.
@@ -1616,6 +1609,9 @@ To enable `debug!` logging, set the RUST_LOG environment variable to the name of
16161609

16171610
## For loops
16181611

1612+
> ***Note:*** The closure-based protocol used `for` loop is on the way out. The `for` loop will
1613+
> use iterator objects in the future instead.
1614+
16191615
The most common way to express iteration in Rust is with a `for`
16201616
loop. Like `do`, `for` is a nice syntax for describing control flow
16211617
with closures. Additionally, within a `for` loop, `break`, `loop`,
@@ -1640,7 +1636,16 @@ fn each(v: &[int], op: &fn(v: &int) -> bool) -> bool {
16401636
And using this function to iterate over a vector:
16411637

16421638
~~~~
1643-
# use each = std::vec::each;
1639+
# fn each(v: &[int], op: &fn(v: &int) -> bool) -> bool {
1640+
# let mut n = 0;
1641+
# while n < v.len() {
1642+
# if !op(&v[n]) {
1643+
# return false;
1644+
# }
1645+
# n += 1;
1646+
# }
1647+
# return true;
1648+
# }
16441649
each([2, 4, 8, 5, 16], |n| {
16451650
if *n % 2 != 0 {
16461651
println("found odd number!");
@@ -1656,7 +1661,16 @@ out of the loop, you just write `break`. To skip ahead
16561661
to the next iteration, write `loop`.
16571662

16581663
~~~~
1659-
# use each = std::vec::each;
1664+
# fn each(v: &[int], op: &fn(v: &int) -> bool) -> bool {
1665+
# let mut n = 0;
1666+
# while n < v.len() {
1667+
# if !op(&v[n]) {
1668+
# return false;
1669+
# }
1670+
# n += 1;
1671+
# }
1672+
# return true;
1673+
# }
16601674
for each([2, 4, 8, 5, 16]) |n| {
16611675
if *n % 2 != 0 {
16621676
println("found odd number!");
@@ -1671,7 +1685,16 @@ normally allowed in closures, in a block that appears as the body of a
16711685
the enclosing function, not just the loop body.
16721686

16731687
~~~~
1674-
# use each = std::vec::each;
1688+
# fn each(v: &[int], op: &fn(v: &int) -> bool) -> bool {
1689+
# let mut n = 0;
1690+
# while n < v.len() {
1691+
# if !op(&v[n]) {
1692+
# return false;
1693+
# }
1694+
# n += 1;
1695+
# }
1696+
# return true;
1697+
# }
16751698
fn contains(v: &[int], elt: int) -> bool {
16761699
for each(v) |x| {
16771700
if (*x == elt) { return true; }
@@ -1686,7 +1709,16 @@ In these situations it can be convenient to lean on Rust's
16861709
argument patterns to bind `x` to the actual value, not the pointer.
16871710

16881711
~~~~
1689-
# use each = std::vec::each;
1712+
# fn each(v: &[int], op: &fn(v: &int) -> bool) -> bool {
1713+
# let mut n = 0;
1714+
# while n < v.len() {
1715+
# if !op(&v[n]) {
1716+
# return false;
1717+
# }
1718+
# n += 1;
1719+
# }
1720+
# return true;
1721+
# }
16901722
# fn contains(v: &[int], elt: int) -> bool {
16911723
for each(v) |&x| {
16921724
if (x == elt) { return true; }
@@ -1841,10 +1873,9 @@ vector consisting of the result of applying `function` to each element
18411873
of `vector`:
18421874

18431875
~~~~
1844-
# use std::vec;
18451876
fn map<T, U>(vector: &[T], function: &fn(v: &T) -> U) -> ~[U] {
18461877
let mut accumulator = ~[];
1847-
for vec::each(vector) |element| {
1878+
for vector.iter().advance |element| {
18481879
accumulator.push(function(element));
18491880
}
18501881
return accumulator;

src/compiletest/runtest.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -529,7 +529,7 @@ fn compose_and_run_compiler(
529529
let extra_link_args = ~[~"-L",
530530
aux_output_dir_name(config, testfile).to_str()];
531531

532-
for vec::each(props.aux_builds) |rel_ab| {
532+
for props.aux_builds.iter().advance |rel_ab| {
533533
let abs_ab = config.aux_base.push_rel(&Path(*rel_ab));
534534
let aux_args =
535535
make_compile_args(config, props, ~[~"--lib"] + extra_link_args,

src/libextra/arc.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -521,6 +521,7 @@ mod tests {
521521
use core::cell::Cell;
522522
use core::comm;
523523
use core::task;
524+
use core::uint;
524525

525526
#[test]
526527
fn manually_share_arc() {
@@ -790,18 +791,20 @@ mod tests {
790791
}
791792
assert_eq!(*state, 42);
792793
*state = 31337;
794+
// FIXME: #7372: hits type inference bug with iterators
793795
// send to other readers
794-
for vec::each(reader_convos) |x| {
795-
match *x {
796+
for uint::range(0, reader_convos.len()) |i| {
797+
match reader_convos[i] {
796798
(ref rc, _) => rc.send(()),
797799
}
798800
}
799801
}
800802
let read_mode = arc.downgrade(write_mode);
801803
do (&read_mode).read |state| {
804+
// FIXME: #7372: hits type inference bug with iterators
802805
// complete handshake with other readers
803-
for vec::each(reader_convos) |x| {
804-
match *x {
806+
for uint::range(0, reader_convos.len()) |i| {
807+
match reader_convos[i] {
805808
(_, ref rp) => rp.recv(),
806809
}
807810
}

src/libextra/getopts.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -418,10 +418,11 @@ pub fn opts_str(mm: &Matches, names: &[~str]) -> ~str {
418418
*/
419419
pub fn opt_strs(mm: &Matches, nm: &str) -> ~[~str] {
420420
let mut acc: ~[~str] = ~[];
421-
for vec::each(opt_vals(mm, nm)) |v| {
421+
let r = opt_vals(mm, nm);
422+
for r.iter().advance |v| {
422423
match *v { Val(ref s) => acc.push(copy *s), _ => () }
423424
}
424-
return acc;
425+
acc
425426
}
426427

427428
/// Returns the string argument supplied to a matching option or none

src/libextra/json.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1123,7 +1123,7 @@ impl Eq for Json {
11231123
&Object(ref d1) => {
11241124
if d0.len() == d1.len() {
11251125
let mut equal = true;
1126-
for d0.each |k, v0| {
1126+
for d0.iter().advance |(k, v0)| {
11271127
match d1.find(k) {
11281128
Some(v1) if v0 == v1 => { },
11291129
_ => { equal = false; break }
@@ -1186,12 +1186,12 @@ impl Ord for Json {
11861186
let mut d1_flat = ~[];
11871187

11881188
// FIXME #4430: this is horribly inefficient...
1189-
for d0.each |k, v| {
1189+
for d0.iter().advance |(k, v)| {
11901190
d0_flat.push((@copy *k, @copy *v));
11911191
}
11921192
d0_flat.qsort();
11931193

1194-
for d1.each |k, v| {
1194+
for d1.iter().advance |(k, v)| {
11951195
d1_flat.push((@copy *k, @copy *v));
11961196
}
11971197
d1_flat.qsort();
@@ -1326,7 +1326,7 @@ impl<A:ToJson> ToJson for ~[A] {
13261326
impl<A:ToJson + Copy> ToJson for HashMap<~str, A> {
13271327
fn to_json(&self) -> Json {
13281328
let mut d = HashMap::new();
1329-
for self.each |key, value| {
1329+
for self.iter().advance |(key, value)| {
13301330
d.insert(copy *key, value.to_json());
13311331
}
13321332
Object(~d)

src/libextra/net_url.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ pub fn encode_form_urlencoded(m: &HashMap<~str, ~[~str]>) -> ~str {
207207
let mut out = ~"";
208208
let mut first = true;
209209

210-
for m.each |key, values| {
210+
for m.iter().advance |(key, values)| {
211211
let key = encode_plus(*key);
212212

213213
for values.iter().advance |value| {

src/libextra/serialize.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -710,7 +710,7 @@ impl<
710710
fn encode(&self, e: &mut E) {
711711
do e.emit_map(self.len()) |e| {
712712
let mut i = 0;
713-
for self.each |key, val| {
713+
for self.iter().advance |(key, val)| {
714714
e.emit_map_elt_key(i, |e| key.encode(e));
715715
e.emit_map_elt_val(i, |e| val.encode(e));
716716
i += 1;
@@ -744,7 +744,7 @@ impl<
744744
fn encode(&self, s: &mut S) {
745745
do s.emit_seq(self.len()) |s| {
746746
let mut i = 0;
747-
for self.each |e| {
747+
for self.iter().advance |e| {
748748
s.emit_seq_elt(i, |s| e.encode(s));
749749
i += 1;
750750
}

src/libextra/smallintmap.rs

Lines changed: 32 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -56,38 +56,6 @@ impl<V> Map<uint, V> for SmallIntMap<V> {
5656
self.find(key).is_some()
5757
}
5858

59-
/// Visit all key-value pairs in order
60-
fn each<'a>(&'a self, it: &fn(&uint, &'a V) -> bool) -> bool {
61-
for uint::range(0, self.v.len()) |i| {
62-
match self.v[i] {
63-
Some(ref elt) => if !it(&i, elt) { return false; },
64-
None => ()
65-
}
66-
}
67-
return true;
68-
}
69-
70-
/// Visit all keys in order
71-
fn each_key(&self, blk: &fn(key: &uint) -> bool) -> bool {
72-
self.each(|k, _| blk(k))
73-
}
74-
75-
/// Visit all values in order
76-
fn each_value<'a>(&'a self, blk: &fn(value: &'a V) -> bool) -> bool {
77-
self.each(|_, v| blk(v))
78-
}
79-
80-
/// Iterate over the map and mutate the contained values
81-
fn mutate_values(&mut self, it: &fn(&uint, &mut V) -> bool) -> bool {
82-
for uint::range(0, self.v.len()) |i| {
83-
match self.v[i] {
84-
Some(ref mut elt) => if !it(&i, elt) { return false; },
85-
None => ()
86-
}
87-
}
88-
return true;
89-
}
90-
9159
/// Return a reference to the value corresponding to the key
9260
fn find<'a>(&'a self, key: &uint) -> Option<&'a V> {
9361
if *key < self.v.len() {
@@ -156,6 +124,38 @@ impl<V> SmallIntMap<V> {
156124
/// Create an empty SmallIntMap
157125
pub fn new() -> SmallIntMap<V> { SmallIntMap{v: ~[]} }
158126

127+
/// Visit all key-value pairs in order
128+
pub fn each<'a>(&'a self, it: &fn(&uint, &'a V) -> bool) -> bool {
129+
for uint::range(0, self.v.len()) |i| {
130+
match self.v[i] {
131+
Some(ref elt) => if !it(&i, elt) { return false; },
132+
None => ()
133+
}
134+
}
135+
return true;
136+
}
137+
138+
/// Visit all keys in order
139+
pub fn each_key(&self, blk: &fn(key: &uint) -> bool) -> bool {
140+
self.each(|k, _| blk(k))
141+
}
142+
143+
/// Visit all values in order
144+
pub fn each_value<'a>(&'a self, blk: &fn(value: &'a V) -> bool) -> bool {
145+
self.each(|_, v| blk(v))
146+
}
147+
148+
/// Iterate over the map and mutate the contained values
149+
pub fn mutate_values(&mut self, it: &fn(&uint, &mut V) -> bool) -> bool {
150+
for uint::range(0, self.v.len()) |i| {
151+
match self.v[i] {
152+
Some(ref mut elt) => if !it(&i, elt) { return false; },
153+
None => ()
154+
}
155+
}
156+
return true;
157+
}
158+
159159
/// Visit all key-value pairs in reverse order
160160
pub fn each_reverse<'a>(&'a self, it: &fn(uint, &'a V) -> bool) -> bool {
161161
for uint::range_rev(self.v.len(), 0) |i| {

src/libextra/sync.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1094,7 +1094,8 @@ mod tests {
10941094
};
10951095
assert!(result.is_err());
10961096
// child task must have finished by the time try returns
1097-
for vec::each(p.recv()) |p| { p.recv(); } // wait on all its siblings
1097+
let r = p.recv();
1098+
for r.iter().advance |p| { p.recv(); } // wait on all its siblings
10981099
do m.lock_cond |cond| {
10991100
let woken = cond.broadcast();
11001101
assert_eq!(woken, 0);

src/libextra/treemap.rs

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -107,26 +107,6 @@ impl<K: TotalOrd, V> Map<K, V> for TreeMap<K, V> {
107107
self.find(key).is_some()
108108
}
109109

110-
/// Visit all key-value pairs in order
111-
fn each<'a>(&'a self, f: &fn(&'a K, &'a V) -> bool) -> bool {
112-
each(&self.root, f)
113-
}
114-
115-
/// Visit all keys in order
116-
fn each_key(&self, f: &fn(&K) -> bool) -> bool {
117-
self.each(|k, _| f(k))
118-
}
119-
120-
/// Visit all values in order
121-
fn each_value<'a>(&'a self, f: &fn(&'a V) -> bool) -> bool {
122-
self.each(|_, v| f(v))
123-
}
124-
125-
/// Iterate over the map and mutate the contained values
126-
fn mutate_values(&mut self, f: &fn(&K, &mut V) -> bool) -> bool {
127-
mutate_values(&mut self.root, f)
128-
}
129-
130110
/// Return a reference to the value corresponding to the key
131111
fn find<'a>(&'a self, key: &K) -> Option<&'a V> {
132112
let mut current: &'a Option<~TreeNode<K, V>> = &self.root;
@@ -184,6 +164,26 @@ impl<K: TotalOrd, V> TreeMap<K, V> {
184164
/// Create an empty TreeMap
185165
pub fn new() -> TreeMap<K, V> { TreeMap{root: None, length: 0} }
186166

167+
/// Visit all key-value pairs in order
168+
pub fn each<'a>(&'a self, f: &fn(&'a K, &'a V) -> bool) -> bool {
169+
each(&self.root, f)
170+
}
171+
172+
/// Visit all keys in order
173+
pub fn each_key(&self, f: &fn(&K) -> bool) -> bool {
174+
self.each(|k, _| f(k))
175+
}
176+
177+
/// Visit all values in order
178+
pub fn each_value<'a>(&'a self, f: &fn(&'a V) -> bool) -> bool {
179+
self.each(|_, v| f(v))
180+
}
181+
182+
/// Iterate over the map and mutate the contained values
183+
pub fn mutate_values(&mut self, f: &fn(&K, &mut V) -> bool) -> bool {
184+
mutate_values(&mut self.root, f)
185+
}
186+
187187
/// Visit all key-value pairs in reverse order
188188
pub fn each_reverse<'a>(&'a self, f: &fn(&'a K, &'a V) -> bool) -> bool {
189189
each_reverse(&self.root, f)

src/libextra/workcache.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ impl WorkMap {
146146
impl<S:Encoder> Encodable<S> for WorkMap {
147147
fn encode(&self, s: &mut S) {
148148
let mut d = ~[];
149-
for self.each |k, v| {
149+
for self.iter().advance |(k, v)| {
150150
d.push((copy *k, copy *v))
151151
}
152152
sort::tim_sort(d);
@@ -320,7 +320,7 @@ impl TPrep for Prep {
320320
}
321321

322322
fn all_fresh(&self, cat: &str, map: &WorkMap) -> bool {
323-
for map.each |k, v| {
323+
for map.iter().advance |(k, v)| {
324324
if ! self.is_fresh(cat, k.kind, k.name, *v) {
325325
return false;
326326
}

src/librustc/metadata/cstore.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ pub fn have_crate_data(cstore: &CStore, cnum: ast::crate_num) -> bool {
8686

8787
pub fn iter_crate_data(cstore: &CStore,
8888
i: &fn(ast::crate_num, @crate_metadata)) {
89-
for cstore.metas.each |&k, &v| {
89+
for cstore.metas.iter().advance |(&k, &v)| {
9090
i(k, v);
9191
}
9292
}

0 commit comments

Comments
 (0)