diff --git a/src/libcargo/cargo.rc b/src/libcargo/cargo.rc index cff44ed5ef2..af86911426f 100644 --- a/src/libcargo/cargo.rc +++ b/src/libcargo/cargo.rc @@ -495,7 +495,7 @@ pub fn try_parse_sources(filename: &Path, let c = io::read_whole_file_str(filename); match json::from_str(c.get()) { Ok(json::Object(j)) => { - for j.each |k, v| { + for j.each |&(k, v)| { sources.insert(copy *k, parse_source(*k, v)); debug!("source: %s", *k); } diff --git a/src/libcore/container.rs b/src/libcore/container.rs index 2a5ca7d8dfa..36424d1bfaa 100644 --- a/src/libcore/container.rs +++ b/src/libcore/container.rs @@ -29,9 +29,6 @@ pub trait Map: Mutable { /// Return true if the map contains a value for the specified key pure fn contains_key(&self, key: &K) -> bool; - /// Visit all key-value pairs - pure fn each(&self, f: fn(&K, &V) -> bool); - /// Visit all keys pure fn each_key(&self, f: fn(&K) -> bool); diff --git a/src/libcore/hashmap.rs b/src/libcore/hashmap.rs index be785863f71..a69cf4611bb 100644 --- a/src/libcore/hashmap.rs +++ b/src/libcore/hashmap.rs @@ -235,6 +235,23 @@ pub mod linear { } } + impl LinearMap: BaseIter<(&K, &V)> { + /// Visit all key-value pairs + pure fn each(&self, blk: fn(&(&self/K, &self/V)) -> bool) { + for uint::range(0, self.buckets.len()) |i| { + let mut broke = false; + do self.buckets[i].map |bucket| { + if !blk(&(&bucket.key, &bucket.value)) { + broke = true; // FIXME(#3064) just write "break;" + } + }; + if broke { break; } + } + } + pure fn size_hint(&self) -> Option { Some(self.len()) } + } + + impl LinearMap: Container { /// Return the number of elements in the map pure fn len(&self) -> uint { self.size } @@ -262,27 +279,14 @@ pub mod linear { } } - /// Visit all key-value pairs - pure fn each(&self, blk: fn(k: &K, v: &V) -> bool) { - for self.buckets.each |slot| { - let mut broke = false; - do slot.iter |bucket| { - if !blk(&bucket.key, &bucket.value) { - broke = true; // FIXME(#3064) just write "break;" - } - } - if broke { break; } - } - } - /// Visit all keys pure fn each_key(&self, blk: fn(k: &K) -> bool) { - self.each(|k, _| blk(k)) + self.each(|&(k, _)| blk(k)) } /// Visit all values pure fn each_value(&self, blk: fn(v: &V) -> bool) { - self.each(|_, v| blk(v)) + self.each(|&(_, v)| blk(v)) } /// Return the value corresponding to the key in the map @@ -388,7 +392,7 @@ pub mod linear { pure fn eq(&self, other: &LinearMap) -> bool { if self.len() != other.len() { return false; } - for self.each |key, value| { + for self.each |&(key, value)| { match other.find(key) { None => return false, Some(v) => if value != v { return false }, @@ -603,7 +607,7 @@ mod test_map { assert m.insert(i, i*2); } let mut observed = 0; - for m.each |k, v| { + for m.each |&(k, v)| { assert *v == *k * 2; observed |= (1 << *k); } diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs index c414ab0f5f3..f66f6b90e9e 100644 --- a/src/libcore/iter.rs +++ b/src/libcore/iter.rs @@ -27,6 +27,10 @@ pub trait BaseIter { pure fn size_hint(&self) -> Option; } +pub trait ReverseIter: BaseIter { + pure fn each_reverse(&self, blk: fn(&A) -> bool); +} + pub trait ExtendedIter { pure fn eachi(&self, blk: fn(uint, v: &A) -> bool); pure fn all(&self, blk: fn(&A) -> bool) -> bool; diff --git a/src/libcore/option.rs b/src/libcore/option.rs index e5d703eec4a..cfc2cba9226 100644 --- a/src/libcore/option.rs +++ b/src/libcore/option.rs @@ -102,7 +102,7 @@ pub pure fn get_ref(opt: &r/Option) -> &r/T { } #[inline(always)] -pub pure fn map(opt: &Option, f: fn(x: &T) -> U) -> Option { +pub pure fn map(opt: &r/Option, f: fn(x: &r/T) -> U) -> Option { //! Maps a `some` value by reference from one type to another match *opt { Some(ref x) => Some(f(x)), None => None } @@ -193,8 +193,8 @@ pub pure fn get_or_default(opt: Option, def: T) -> T { } #[inline(always)] -pub pure fn map_default(opt: &Option, def: U, - f: fn(x: &T) -> U) -> U { +pub pure fn map_default(opt: &r/Option, def: U, + f: fn(&r/T) -> U) -> U { //! Applies a function to the contained value or returns a default match *opt { None => move def, Some(ref t) => f(t) } @@ -273,7 +273,7 @@ impl Option { /// Maps a `some` value from one type to another by reference #[inline(always)] - pure fn map(&self, f: fn(x: &T) -> U) -> Option { map(self, f) } + pure fn map(&self, f: fn(&self/T) -> U) -> Option { map(self, f) } /// As `map`, but consumes the option and gives `f` ownership to avoid /// copying. @@ -284,7 +284,7 @@ impl Option { /// Applies a function to the contained value or returns a default #[inline(always)] - pure fn map_default(&self, def: U, f: fn(x: &T) -> U) -> U { + pure fn map_default(&self, def: U, f: fn(&self/T) -> U) -> U { map_default(self, move def, f) } diff --git a/src/libstd/json.rs b/src/libstd/json.rs index 99c6c2f008d..d5c91ea5147 100644 --- a/src/libstd/json.rs +++ b/src/libstd/json.rs @@ -302,7 +302,7 @@ pub impl Json: serialize::Encodable { Object(ref v) => { do s.emit_rec || { let mut idx = 0; - for v.each |key, value| { + for v.each |&(key, value)| { do s.emit_field(*key, idx) { value.encode(s); } @@ -936,7 +936,7 @@ impl Json : Eq { &Object(ref d1) => { if d0.len() == d1.len() { let mut equal = true; - for d0.each |k, v0| { + for d0.each |&(k, v0)| { match d1.find(k) { Some(v1) if v0 == v1 => { }, _ => { equal = false; break } @@ -1000,12 +1000,12 @@ impl Json : Ord { let mut d1_flat = ~[]; // FIXME #4430: this is horribly inefficient... - for d0.each |k, v| { + for d0.each |&(k, v)| { d0_flat.push((@copy *k, @copy *v)); } d0_flat.qsort(); - for d1.each |k, v| { + for d1.each |&(k, v)| { d1_flat.push((@copy *k, @copy *v)); } d1_flat.qsort(); @@ -1146,7 +1146,7 @@ impl ~[A]: ToJson { impl LinearMap<~str, A>: ToJson { fn to_json() -> Json { let mut d = LinearMap::new(); - for self.each() |key, value| { + for self.each |&(key, value)| { d.insert(copy *key, value.to_json()); } Object(~d) diff --git a/src/libstd/net_url.rs b/src/libstd/net_url.rs index 9403438dde0..1da3a642514 100644 --- a/src/libstd/net_url.rs +++ b/src/libstd/net_url.rs @@ -219,10 +219,10 @@ pub fn encode_form_urlencoded(m: &LinearMap<~str, ~[~str]>) -> ~str { let mut out = ~""; let mut first = true; - for m.each |key, values| { + for m.each |&(key, values)| { let key = encode_plus(*key); - for (*values).each |value| { + for values.each |value| { if first { first = false; } else { diff --git a/src/libstd/priority_queue.rs b/src/libstd/priority_queue.rs index fcd9f8379b2..5248ab1742e 100644 --- a/src/libstd/priority_queue.rs +++ b/src/libstd/priority_queue.rs @@ -12,6 +12,7 @@ use core::container::{Container, Mutable}; use core::cmp::Ord; +use core::iter::BaseIter; use core::prelude::*; use core::ptr::addr_of; use core::vec; @@ -26,6 +27,14 @@ pub struct PriorityQueue { priv data: ~[T], } +impl PriorityQueue: BaseIter { + /// Visit all values in the underlying vector. + /// + /// The values are **not** visited in order. + pure fn each(&self, f: fn(&T) -> bool) { self.data.each(f) } + pure fn size_hint(&self) -> Option { self.data.size_hint() } +} + impl PriorityQueue: Container { /// Returns the length of the queue pure fn len(&self) -> uint { self.data.len() } diff --git a/src/libstd/smallintmap.rs b/src/libstd/smallintmap.rs index 9af596eb1f5..9642dd0c3dd 100644 --- a/src/libstd/smallintmap.rs +++ b/src/libstd/smallintmap.rs @@ -14,6 +14,7 @@ */ use core::container::{Container, Mutable, Map, Set}; +use core::iter::{BaseIter, ReverseIter}; use core::option::{Some, None}; use core::prelude::*; @@ -21,6 +22,32 @@ pub struct SmallIntMap { priv v: ~[Option], } +impl SmallIntMap: BaseIter<(uint, &V)> { + /// Visit all key-value pairs in order + pure fn each(&self, it: fn(&(uint, &self/V)) -> bool) { + for uint::range(0, self.v.len()) |i| { + match self.v[i] { + Some(ref elt) => if !it(&(i, elt)) { break }, + None => () + } + } + } + + pure fn size_hint(&self) -> Option { Some(self.len()) } +} + +impl SmallIntMap: ReverseIter<(uint, &V)> { + /// Visit all key-value pairs in reverse order + pure fn each_reverse(&self, it: fn(&(uint, &self/V)) -> bool) { + for uint::range_rev(self.v.len(), 0) |i| { + match self.v[i - 1] { + Some(ref elt) => if !it(&(i - 1, elt)) { break }, + None => () + } + } + } +} + impl SmallIntMap: Container { /// Return the number of elements in the map pure fn len(&self) -> uint { @@ -48,24 +75,14 @@ impl SmallIntMap: Map { self.find(key).is_some() } - /// Visit all key-value pairs - pure fn each(&self, it: fn(key: &uint, value: &V) -> bool) { - for uint::range(0, self.v.len()) |i| { - match self.v[i] { - Some(ref elt) => if !it(&i, elt) { break }, - None => () - } - } - } - - /// Visit all keys + /// Visit all keys in order pure fn each_key(&self, blk: fn(key: &uint) -> bool) { - self.each(|k, _| blk(k)) + self.each(|&(k, _)| blk(&k)) } - /// Visit all values + /// Visit all values in order pure fn each_value(&self, blk: fn(value: &V) -> bool) { - self.each(|_, v| blk(v)) + self.each(|&(_, v)| blk(v)) } /// Return the value corresponding to the key in the map diff --git a/src/libstd/treemap.rs b/src/libstd/treemap.rs index 1e90abcc03d..d8deea60725 100644 --- a/src/libstd/treemap.rs +++ b/src/libstd/treemap.rs @@ -14,6 +14,7 @@ use core::container::{Container, Mutable, Map, Set}; use core::cmp::{Eq, Ord}; +use core::iter::{BaseIter, ReverseIter}; use core::option::{Option, Some, None}; use core::prelude::*; @@ -103,6 +104,21 @@ impl TreeMap: Ord { } } +impl TreeMap: BaseIter<(&K, &V)> { + /// Visit all key-value pairs in order + pure fn each(&self, f: fn(&(&self/K, &self/V)) -> bool) { + each(&self.root, f) + } + pure fn size_hint(&self) -> Option { Some(self.len()) } +} + +impl TreeMap: ReverseIter<(&K, &V)> { + /// Visit all key-value pairs in reverse order + pure fn each_reverse(&self, f: fn(&(&self/K, &self/V)) -> bool) { + each_reverse(&self.root, f); + } +} + impl TreeMap: Container { /// Return the number of elements in the map pure fn len(&self) -> uint { self.length } @@ -125,14 +141,11 @@ impl TreeMap: Map { self.find(key).is_some() } - /// Visit all key-value pairs in order - pure fn each(&self, f: fn(&K, &V) -> bool) { each(&self.root, f) } - /// Visit all keys in order - pure fn each_key(&self, f: fn(&K) -> bool) { self.each(|k, _| f(k)) } + pure fn each_key(&self, f: fn(&K) -> bool) { self.each(|&(k, _)| f(k)) } /// Visit all values in order - pure fn each_value(&self, f: fn(&V) -> bool) { self.each(|_, v| f(v)) } + pure fn each_value(&self, f: fn(&V) -> bool) { self.each(|&(_, v)| f(v)) } /// Return the value corresponding to the key in the map pure fn find(&self, key: &K) -> Option<&self/V> { @@ -175,19 +188,14 @@ impl TreeMap { /// Create an empty TreeMap static pure fn new() -> TreeMap { TreeMap{root: None, length: 0} } - /// Visit all key-value pairs in reverse order - pure fn each_reverse(&self, f: fn(&K, &V) -> bool) { - each_reverse(&self.root, f); - } - /// Visit all keys in reverse order pure fn each_key_reverse(&self, f: fn(&K) -> bool) { - self.each_reverse(|k, _| f(k)) + self.each_reverse(|&(k, _)| f(k)) } /// Visit all values in reverse order pure fn each_value_reverse(&self, f: fn(&V) -> bool) { - self.each_reverse(|_, v| f(v)) + self.each_reverse(|&(_, v)| f(v)) } /// Get a lazy iterator over the key-value pairs in the map. @@ -238,12 +246,19 @@ pub struct TreeSet { priv map: TreeMap } -impl TreeSet: iter::BaseIter { +impl TreeSet: BaseIter { /// Visit all values in order pure fn each(&self, f: fn(&T) -> bool) { self.map.each_key(f) } pure fn size_hint(&self) -> Option { Some(self.len()) } } +impl TreeSet: ReverseIter { + /// Visit all values in reverse order + pure fn each_reverse(&self, f: fn(&T) -> bool) { + self.map.each_key_reverse(f) + } +} + impl TreeSet: Eq { pure fn eq(&self, other: &TreeSet) -> bool { self.map == other.map } pure fn ne(&self, other: &TreeSet) -> bool { self.map != other.map } @@ -499,11 +514,6 @@ impl TreeSet { /// Create an empty TreeSet static pure fn new() -> TreeSet { TreeSet{map: TreeMap::new()} } - /// Visit all values in reverse order - pure fn each_reverse(&self, f: fn(&T) -> bool) { - self.map.each_key_reverse(f) - } - /// Get a lazy iterator over the values in the set. /// Requires that it be frozen (immutable). pure fn iter(&self) -> TreeSetIterator/&self { @@ -549,19 +559,19 @@ impl TreeNode { } } -pure fn each(node: &Option<~TreeNode>, - f: fn(&K, &V) -> bool) { +pure fn each(node: &r/Option<~TreeNode>, + f: fn(&(&r/K, &r/V)) -> bool) { do node.map |x| { each(&x.left, f); - if f(&x.key, &x.value) { each(&x.right, f) } + if f(&(&x.key, &x.value)) { each(&x.right, f) } }; } -pure fn each_reverse(node: &Option<~TreeNode>, - f: fn(&K, &V) -> bool) { +pure fn each_reverse(node: &r/Option<~TreeNode>, + f: fn(&(&r/K, &r/V)) -> bool) { do node.map |x| { each_reverse(&x.right, f); - if f(&x.key, &x.value) { each_reverse(&x.left, f) } + if f(&(&x.key, &x.value)) { each_reverse(&x.left, f) } }; } @@ -754,7 +764,7 @@ mod test_treemap { let &(k, v) = x; assert map.find(&k).unwrap() == &v } - for map.each |map_k, map_v| { + for map.each |&(map_k, map_v)| { let mut found = false; for ctrl.each |x| { let &(ctrl_k, ctrl_v) = x; @@ -868,7 +878,7 @@ mod test_treemap { assert m.insert(1, 2); let mut n = 0; - for m.each |k, v| { + for m.each |&(k, v)| { assert *k == n; assert *v == n * 2; n += 1; @@ -886,7 +896,7 @@ mod test_treemap { assert m.insert(1, 2); let mut n = 4; - for m.each_reverse |k, v| { + for m.each_reverse |&(k, v)| { assert *k == n; assert *v == n * 2; n -= 1; diff --git a/src/libstd/workcache.rs b/src/libstd/workcache.rs index b828c4ef629..593d26d0124 100644 --- a/src/libstd/workcache.rs +++ b/src/libstd/workcache.rs @@ -142,7 +142,7 @@ type WorkMap = LinearMap; pub impl WorkMap: Encodable { fn encode(&self, s: &S) { let d = dvec::DVec(); - for self.each |k, v| { + for self.each |&(k, v)| { d.push((copy *k, copy *v)) } let mut v = d.get(); @@ -155,7 +155,7 @@ pub impl WorkMap: Decodable { static fn decode(&self, d: &D) -> WorkMap { let v : ~[(WorkKey,~str)] = Decodable::decode(d); let mut w = LinearMap::new(); - for v.each |&(k,v)| { + for v.each |&(k, v)| { w.insert(copy k, copy v); } w @@ -312,7 +312,7 @@ impl @Mut : TPrep { } fn all_fresh(&self, cat: &str, map: &WorkMap) -> bool { - for map.each |k,v| { + for map.each |&(k, v)| { if ! self.is_fresh(cat, k.kind, k.name, *v) { return false; } diff --git a/src/test/run-pass/class-impl-very-parameterized-trait.rs b/src/test/run-pass/class-impl-very-parameterized-trait.rs index b7c8322316f..a0230d02981 100644 --- a/src/test/run-pass/class-impl-very-parameterized-trait.rs +++ b/src/test/run-pass/class-impl-very-parameterized-trait.rs @@ -11,6 +11,7 @@ // xfail-fast use core::container::{Container, Mutable, Map}; +use core::iter::BaseIter; enum cat_type { tuxedo, tabby, tortoiseshell } @@ -48,6 +49,18 @@ impl cat { } } +impl cat: BaseIter<(int, &T)> { + pure fn each(&self, f: fn(&(int, &self/T)) -> bool) { + let mut n = int::abs(self.meows); + while n > 0 { + if !f(&(n, &self.name)) { break; } + n -= 1; + } + } + + pure fn size_hint(&self) -> Option { Some(self.len()) } +} + impl cat: Container { pure fn len(&self) -> uint { self.meows as uint } pure fn is_empty(&self) -> bool { self.meows == 0 } @@ -60,20 +73,12 @@ impl cat: Mutable { impl cat: Map { pure fn contains_key(&self, k: &int) -> bool { *k <= self.meows } - pure fn each(&self, f: fn(v: &int, v: &T) -> bool) { - let mut n = int::abs(self.meows); - while n > 0 { - if !f(&n, &self.name) { break; } - n -= 1; - } - } - pure fn each_key(&self, f: fn(v: &int) -> bool) { - for self.each |k, _| { if !f(k) { break; } loop;}; + for self.each |&(k, _)| { if !f(&k) { break; } loop;}; } pure fn each_value(&self, f: fn(v: &T) -> bool) { - for self.each |_, v| { if !f(v) { break; } loop;}; + for self.each |&(_, v)| { if !f(v) { break; } loop;}; } fn insert(&mut self, k: int, _: T) -> bool {