Skip to content

Commit 9b4fa84

Browse files
committed
auto merge of #4835 : thestinger/rust/iterator, r=graydon
This adds a `BaseIter` impl to `PriorityQueue`, `TreeMap`, `LinearMap` and `SmallIntMap`, and introduces a `ReverseIter` trait + implementations for `TreeMap`, `TreeSet` and `SmallIntMap`.
2 parents e8fc4b3 + 8c32cd2 commit 9b4fa84

12 files changed

+133
-87
lines changed

src/libcargo/cargo.rc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -495,7 +495,7 @@ pub fn try_parse_sources(filename: &Path,
495495
let c = io::read_whole_file_str(filename);
496496
match json::from_str(c.get()) {
497497
Ok(json::Object(j)) => {
498-
for j.each |k, v| {
498+
for j.each |&(k, v)| {
499499
sources.insert(copy *k, parse_source(*k, v));
500500
debug!("source: %s", *k);
501501
}

src/libcore/container.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,6 @@ pub trait Map<K, V>: Mutable {
2929
/// Return true if the map contains a value for the specified key
3030
pure fn contains_key(&self, key: &K) -> bool;
3131

32-
/// Visit all key-value pairs
33-
pure fn each(&self, f: fn(&K, &V) -> bool);
34-
3532
/// Visit all keys
3633
pure fn each_key(&self, f: fn(&K) -> bool);
3734

src/libcore/hashmap.rs

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,23 @@ pub mod linear {
235235
}
236236
}
237237
238+
impl <K: Hash IterBytes Eq, V> LinearMap<K, V>: BaseIter<(&K, &V)> {
239+
/// Visit all key-value pairs
240+
pure fn each(&self, blk: fn(&(&self/K, &self/V)) -> bool) {
241+
for uint::range(0, self.buckets.len()) |i| {
242+
let mut broke = false;
243+
do self.buckets[i].map |bucket| {
244+
if !blk(&(&bucket.key, &bucket.value)) {
245+
broke = true; // FIXME(#3064) just write "break;"
246+
}
247+
};
248+
if broke { break; }
249+
}
250+
}
251+
pure fn size_hint(&self) -> Option<uint> { Some(self.len()) }
252+
}
253+
254+
238255
impl <K: Hash IterBytes Eq, V> LinearMap<K, V>: Container {
239256
/// Return the number of elements in the map
240257
pure fn len(&self) -> uint { self.size }
@@ -262,27 +279,14 @@ pub mod linear {
262279
}
263280
}
264281
265-
/// Visit all key-value pairs
266-
pure fn each(&self, blk: fn(k: &K, v: &V) -> bool) {
267-
for self.buckets.each |slot| {
268-
let mut broke = false;
269-
do slot.iter |bucket| {
270-
if !blk(&bucket.key, &bucket.value) {
271-
broke = true; // FIXME(#3064) just write "break;"
272-
}
273-
}
274-
if broke { break; }
275-
}
276-
}
277-
278282
/// Visit all keys
279283
pure fn each_key(&self, blk: fn(k: &K) -> bool) {
280-
self.each(|k, _| blk(k))
284+
self.each(|&(k, _)| blk(k))
281285
}
282286
283287
/// Visit all values
284288
pure fn each_value(&self, blk: fn(v: &V) -> bool) {
285-
self.each(|_, v| blk(v))
289+
self.each(|&(_, v)| blk(v))
286290
}
287291
288292
/// Return the value corresponding to the key in the map
@@ -388,7 +392,7 @@ pub mod linear {
388392
pure fn eq(&self, other: &LinearMap<K, V>) -> bool {
389393
if self.len() != other.len() { return false; }
390394

391-
for self.each |key, value| {
395+
for self.each |&(key, value)| {
392396
match other.find(key) {
393397
None => return false,
394398
Some(v) => if value != v { return false },
@@ -603,7 +607,7 @@ mod test_map {
603607
assert m.insert(i, i*2);
604608
}
605609
let mut observed = 0;
606-
for m.each |k, v| {
610+
for m.each |&(k, v)| {
607611
assert *v == *k * 2;
608612
observed |= (1 << *k);
609613
}

src/libcore/iter.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@ pub trait BaseIter<A> {
2727
pure fn size_hint(&self) -> Option<uint>;
2828
}
2929

30+
pub trait ReverseIter<A>: BaseIter<A> {
31+
pure fn each_reverse(&self, blk: fn(&A) -> bool);
32+
}
33+
3034
pub trait ExtendedIter<A> {
3135
pure fn eachi(&self, blk: fn(uint, v: &A) -> bool);
3236
pure fn all(&self, blk: fn(&A) -> bool) -> bool;

src/libcore/option.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ pub pure fn get_ref<T>(opt: &r/Option<T>) -> &r/T {
102102
}
103103
104104
#[inline(always)]
105-
pub pure fn map<T, U>(opt: &Option<T>, f: fn(x: &T) -> U) -> Option<U> {
105+
pub pure fn map<T, U>(opt: &r/Option<T>, f: fn(x: &r/T) -> U) -> Option<U> {
106106
//! Maps a `some` value by reference from one type to another
107107
108108
match *opt { Some(ref x) => Some(f(x)), None => None }
@@ -193,8 +193,8 @@ pub pure fn get_or_default<T: Copy>(opt: Option<T>, def: T) -> T {
193193
}
194194
195195
#[inline(always)]
196-
pub pure fn map_default<T, U>(opt: &Option<T>, def: U,
197-
f: fn(x: &T) -> U) -> U {
196+
pub pure fn map_default<T, U>(opt: &r/Option<T>, def: U,
197+
f: fn(&r/T) -> U) -> U {
198198
//! Applies a function to the contained value or returns a default
199199
200200
match *opt { None => move def, Some(ref t) => f(t) }
@@ -273,7 +273,7 @@ impl<T> Option<T> {
273273
274274
/// Maps a `some` value from one type to another by reference
275275
#[inline(always)]
276-
pure fn map<U>(&self, f: fn(x: &T) -> U) -> Option<U> { map(self, f) }
276+
pure fn map<U>(&self, f: fn(&self/T) -> U) -> Option<U> { map(self, f) }
277277
278278
/// As `map`, but consumes the option and gives `f` ownership to avoid
279279
/// copying.
@@ -284,7 +284,7 @@ impl<T> Option<T> {
284284
285285
/// Applies a function to the contained value or returns a default
286286
#[inline(always)]
287-
pure fn map_default<U>(&self, def: U, f: fn(x: &T) -> U) -> U {
287+
pure fn map_default<U>(&self, def: U, f: fn(&self/T) -> U) -> U {
288288
map_default(self, move def, f)
289289
}
290290

src/libstd/json.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,7 @@ pub impl<S: serialize::Encoder> Json: serialize::Encodable<S> {
302302
Object(ref v) => {
303303
do s.emit_rec || {
304304
let mut idx = 0;
305-
for v.each |key, value| {
305+
for v.each |&(key, value)| {
306306
do s.emit_field(*key, idx) {
307307
value.encode(s);
308308
}
@@ -936,7 +936,7 @@ impl Json : Eq {
936936
&Object(ref d1) => {
937937
if d0.len() == d1.len() {
938938
let mut equal = true;
939-
for d0.each |k, v0| {
939+
for d0.each |&(k, v0)| {
940940
match d1.find(k) {
941941
Some(v1) if v0 == v1 => { },
942942
_ => { equal = false; break }
@@ -1000,12 +1000,12 @@ impl Json : Ord {
10001000
let mut d1_flat = ~[];
10011001
10021002
// FIXME #4430: this is horribly inefficient...
1003-
for d0.each |k, v| {
1003+
for d0.each |&(k, v)| {
10041004
d0_flat.push((@copy *k, @copy *v));
10051005
}
10061006
d0_flat.qsort();
10071007
1008-
for d1.each |k, v| {
1008+
for d1.each |&(k, v)| {
10091009
d1_flat.push((@copy *k, @copy *v));
10101010
}
10111011
d1_flat.qsort();
@@ -1146,7 +1146,7 @@ impl <A: ToJson> ~[A]: ToJson {
11461146
impl <A: ToJson Copy> LinearMap<~str, A>: ToJson {
11471147
fn to_json() -> Json {
11481148
let mut d = LinearMap::new();
1149-
for self.each() |key, value| {
1149+
for self.each |&(key, value)| {
11501150
d.insert(copy *key, value.to_json());
11511151
}
11521152
Object(~d)

src/libstd/net_url.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -219,10 +219,10 @@ pub fn encode_form_urlencoded(m: &LinearMap<~str, ~[~str]>) -> ~str {
219219
let mut out = ~"";
220220
let mut first = true;
221221

222-
for m.each |key, values| {
222+
for m.each |&(key, values)| {
223223
let key = encode_plus(*key);
224224

225-
for (*values).each |value| {
225+
for values.each |value| {
226226
if first {
227227
first = false;
228228
} else {

src/libstd/priority_queue.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
1313
use core::container::{Container, Mutable};
1414
use core::cmp::Ord;
15+
use core::iter::BaseIter;
1516
use core::prelude::*;
1617
use core::ptr::addr_of;
1718
use core::vec;
@@ -26,6 +27,14 @@ pub struct PriorityQueue<T> {
2627
priv data: ~[T],
2728
}
2829

30+
impl <T: Ord> PriorityQueue<T>: BaseIter<T> {
31+
/// Visit all values in the underlying vector.
32+
///
33+
/// The values are **not** visited in order.
34+
pure fn each(&self, f: fn(&T) -> bool) { self.data.each(f) }
35+
pure fn size_hint(&self) -> Option<uint> { self.data.size_hint() }
36+
}
37+
2938
impl <T: Ord> PriorityQueue<T>: Container {
3039
/// Returns the length of the queue
3140
pure fn len(&self) -> uint { self.data.len() }

src/libstd/smallintmap.rs

Lines changed: 31 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,40 @@
1414
*/
1515

1616
use core::container::{Container, Mutable, Map, Set};
17+
use core::iter::{BaseIter, ReverseIter};
1718
use core::option::{Some, None};
1819
use core::prelude::*;
1920

2021
pub struct SmallIntMap<T> {
2122
priv v: ~[Option<T>],
2223
}
2324

25+
impl<V> SmallIntMap<V>: BaseIter<(uint, &V)> {
26+
/// Visit all key-value pairs in order
27+
pure fn each(&self, it: fn(&(uint, &self/V)) -> bool) {
28+
for uint::range(0, self.v.len()) |i| {
29+
match self.v[i] {
30+
Some(ref elt) => if !it(&(i, elt)) { break },
31+
None => ()
32+
}
33+
}
34+
}
35+
36+
pure fn size_hint(&self) -> Option<uint> { Some(self.len()) }
37+
}
38+
39+
impl<V> SmallIntMap<V>: ReverseIter<(uint, &V)> {
40+
/// Visit all key-value pairs in reverse order
41+
pure fn each_reverse(&self, it: fn(&(uint, &self/V)) -> bool) {
42+
for uint::range_rev(self.v.len(), 0) |i| {
43+
match self.v[i - 1] {
44+
Some(ref elt) => if !it(&(i - 1, elt)) { break },
45+
None => ()
46+
}
47+
}
48+
}
49+
}
50+
2451
impl<V> SmallIntMap<V>: Container {
2552
/// Return the number of elements in the map
2653
pure fn len(&self) -> uint {
@@ -48,24 +75,14 @@ impl<V> SmallIntMap<V>: Map<uint, V> {
4875
self.find(key).is_some()
4976
}
5077

51-
/// Visit all key-value pairs
52-
pure fn each(&self, it: fn(key: &uint, value: &V) -> bool) {
53-
for uint::range(0, self.v.len()) |i| {
54-
match self.v[i] {
55-
Some(ref elt) => if !it(&i, elt) { break },
56-
None => ()
57-
}
58-
}
59-
}
60-
61-
/// Visit all keys
78+
/// Visit all keys in order
6279
pure fn each_key(&self, blk: fn(key: &uint) -> bool) {
63-
self.each(|k, _| blk(k))
80+
self.each(|&(k, _)| blk(&k))
6481
}
6582

66-
/// Visit all values
83+
/// Visit all values in order
6784
pure fn each_value(&self, blk: fn(value: &V) -> bool) {
68-
self.each(|_, v| blk(v))
85+
self.each(|&(_, v)| blk(v))
6986
}
7087

7188
/// Return the value corresponding to the key in the map

0 commit comments

Comments
 (0)