Skip to content

Commit cb58b19

Browse files
committed
auto merge of #7319 : thestinger/rust/hashmap-iterator, r=thestinger
#7277
2 parents c17ff80 + ac2e167 commit cb58b19

File tree

2 files changed

+109
-29
lines changed

2 files changed

+109
-29
lines changed

src/libstd/hashmap.rs

Lines changed: 106 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,13 @@
1818
use container::{Container, Mutable, Map, Set};
1919
use cmp::{Eq, Equiv};
2020
use hash::Hash;
21-
use old_iter::BaseIter;
22-
use old_iter;
23-
use iterator::IteratorUtil;
21+
use iterator::{Iterator, IteratorUtil};
2422
use option::{None, Option, Some};
2523
use rand::RngUtil;
2624
use rand;
2725
use uint;
2826
use vec;
29-
use vec::ImmutableVector;
27+
use vec::{ImmutableVector, MutableVector};
3028
use kinds::Copy;
3129
use util::{replace, unreachable};
3230

@@ -311,24 +309,17 @@ impl<K:Hash + Eq,V> Map<K, V> for HashMap<K, V> {
311309

312310
/// Visit all key-value pairs
313311
fn each<'a>(&'a self, blk: &fn(&K, &'a V) -> bool) -> bool {
314-
for self.buckets.iter().advance |bucket| {
315-
for bucket.iter().advance |pair| {
316-
if !blk(&pair.key, &pair.value) {
317-
return false;
318-
}
319-
}
320-
}
321-
return true;
312+
self.iter().advance(|(k, v)| blk(k, v))
322313
}
323314

324315
/// Visit all keys
325316
fn each_key(&self, blk: &fn(k: &K) -> bool) -> bool {
326-
self.each(|k, _| blk(k))
317+
self.iter().advance(|(k, _)| blk(k))
327318
}
328319

329320
/// Visit all values
330321
fn each_value<'a>(&'a self, blk: &fn(v: &'a V) -> bool) -> bool {
331-
self.each(|_, v| blk(v))
322+
self.iter().advance(|(_, v)| blk(v))
332323
}
333324

334325
/// Iterate over the map and mutate the contained values
@@ -524,6 +515,19 @@ impl<K: Hash + Eq, V> HashMap<K, V> {
524515
TableFull | FoundHole(_) => None,
525516
}
526517
}
518+
519+
/// An iterator visiting all key-value pairs in arbitrary order.
520+
/// Iterator element type is (&'a K, &'a V).
521+
pub fn iter<'a>(&'a self) -> HashMapIterator<'a, K, V> {
522+
HashMapIterator { iter: self.buckets.iter() }
523+
}
524+
525+
/// An iterator visiting all key-value pairs in arbitrary order,
526+
/// with mutable references to the values.
527+
/// Iterator element type is (&'a K, &'a mut V).
528+
pub fn mut_iter<'a>(&'a mut self) -> HashMapMutIterator<'a, K, V> {
529+
HashMapMutIterator { iter: self.buckets.mut_iter() }
530+
}
527531
}
528532

529533
impl<K: Hash + Eq, V: Copy> HashMap<K, V> {
@@ -542,7 +546,7 @@ impl<K:Hash + Eq,V:Eq> Eq for HashMap<K, V> {
542546
fn eq(&self, other: &HashMap<K, V>) -> bool {
543547
if self.len() != other.len() { return false; }
544548

545-
for self.each |key, value| {
549+
for self.iter().advance |(key, value)| {
546550
match other.find(key) {
547551
None => return false,
548552
Some(v) => if value != v { return false },
@@ -555,19 +559,68 @@ impl<K:Hash + Eq,V:Eq> Eq for HashMap<K, V> {
555559
fn ne(&self, other: &HashMap<K, V>) -> bool { !self.eq(other) }
556560
}
557561

562+
/// HashMap iterator
563+
pub struct HashMapIterator<'self, K, V> {
564+
priv iter: vec::VecIterator<'self, Option<Bucket<K, V>>>,
565+
}
566+
567+
/// HashMap mutable values iterator
568+
pub struct HashMapMutIterator<'self, K, V> {
569+
priv iter: vec::VecMutIterator<'self, Option<Bucket<K, V>>>,
570+
}
571+
572+
/// HashSet iterator
573+
pub struct HashSetIterator<'self, K> {
574+
priv iter: vec::VecIterator<'self, Option<Bucket<K, ()>>>,
575+
}
576+
577+
impl<'self, K, V> Iterator<(&'self K, &'self V)> for HashMapIterator<'self, K, V> {
578+
#[inline]
579+
fn next(&mut self) -> Option<(&'self K, &'self V)> {
580+
for self.iter.advance |elt| {
581+
match elt {
582+
&Some(ref bucket) => return Some((&bucket.key, &bucket.value)),
583+
&None => {},
584+
}
585+
}
586+
None
587+
}
588+
}
589+
590+
impl<'self, K, V> Iterator<(&'self K, &'self mut V)> for HashMapMutIterator<'self, K, V> {
591+
#[inline]
592+
fn next(&mut self) -> Option<(&'self K, &'self mut V)> {
593+
for self.iter.advance |elt| {
594+
match elt {
595+
&Some(ref mut bucket) => return Some((&bucket.key, &mut bucket.value)),
596+
&None => {},
597+
}
598+
}
599+
None
600+
}
601+
}
602+
603+
impl<'self, K> Iterator<&'self K> for HashSetIterator<'self, K> {
604+
#[inline]
605+
fn next(&mut self) -> Option<&'self K> {
606+
for self.iter.advance |elt| {
607+
match elt {
608+
&Some(ref bucket) => return Some(&bucket.key),
609+
&None => {},
610+
}
611+
}
612+
None
613+
}
614+
}
615+
616+
558617
/// An implementation of a hash set using the underlying representation of a
559618
/// HashMap where the value is (). As with the `HashMap` type, a `HashSet`
560619
/// requires that the elements implement the `Eq` and `Hash` traits.
561620
pub struct HashSet<T> {
562621
priv map: HashMap<T, ()>
563622
}
564623

565-
impl<T:Hash + Eq> BaseIter<T> for HashSet<T> {
566-
/// Visit all values in order
567-
fn each(&self, f: &fn(&T) -> bool) -> bool { self.map.each_key(f) }
568-
fn size_hint(&self) -> Option<uint> { Some(self.len()) }
569-
}
570-
571624
impl<T:Hash + Eq> Eq for HashSet<T> {
572625
fn eq(&self, other: &HashSet<T>) -> bool { self.map == other.map }
573626
fn ne(&self, other: &HashSet<T>) -> bool { self.map != other.map }
@@ -601,12 +654,12 @@ impl<T:Hash + Eq> Set<T> for HashSet<T> {
601654
/// Return true if the set has no elements in common with `other`.
602655
/// This is equivalent to checking for an empty intersection.
603656
fn is_disjoint(&self, other: &HashSet<T>) -> bool {
604-
old_iter::all(self, |v| !other.contains(v))
657+
self.iter().all(|v| !other.contains(v))
605658
}
606659

607660
/// Return true if the set is a subset of another
608661
fn is_subset(&self, other: &HashSet<T>) -> bool {
609-
old_iter::all(self, |v| other.contains(v))
662+
self.iter().all(|v| other.contains(v))
610663
}
611664

612665
/// Return true if the set is a superset of another
@@ -616,7 +669,7 @@ impl<T:Hash + Eq> Set<T> for HashSet<T> {
616669

617670
/// Visit the values representing the difference
618671
fn difference(&self, other: &HashSet<T>, f: &fn(&T) -> bool) -> bool {
619-
self.each(|v| other.contains(v) || f(v))
672+
self.iter().advance(|v| other.contains(v) || f(v))
620673
}
621674

622675
/// Visit the values representing the symmetric difference
@@ -628,12 +681,12 @@ impl<T:Hash + Eq> Set<T> for HashSet<T> {
628681

629682
/// Visit the values representing the intersection
630683
fn intersection(&self, other: &HashSet<T>, f: &fn(&T) -> bool) -> bool {
631-
self.each(|v| !other.contains(v) || f(v))
684+
self.iter().advance(|v| !other.contains(v) || f(v))
632685
}
633686

634687
/// Visit the values representing the union
635688
fn union(&self, other: &HashSet<T>, f: &fn(&T) -> bool) -> bool {
636-
self.each(f) && other.each(|v| self.contains(v) || f(v))
689+
self.iter().advance(f) && other.iter().advance(|v| self.contains(v) || f(v))
637690
}
638691
}
639692

@@ -664,6 +717,18 @@ impl<T:Hash + Eq> HashSet<T> {
664717
pub fn contains_equiv<Q:Hash + Equiv<T>>(&self, value: &Q) -> bool {
665718
self.map.contains_key_equiv(value)
666719
}
720+
721+
/// Visit all elements in arbitrary order
722+
/// FIXME: #6978: Remove when all callers are converted
723+
pub fn each(&self, f: &fn(&T) -> bool) -> bool {
724+
self.iter().advance(f)
725+
}
726+
727+
/// An iterator visiting all elements in arbitrary order.
728+
/// Iterator element type is &'a T.
729+
pub fn iter<'a>(&'a self) -> HashSetIterator<'a, T> {
730+
HashSetIterator { iter: self.map.buckets.iter() }
731+
}
667732
}
668733

669734
#[cfg(test)]
@@ -808,7 +873,7 @@ mod test_map {
808873
assert!(m.insert(i, i*2));
809874
}
810875
let mut observed = 0;
811-
for m.each |k, v| {
876+
for m.iter().advance |(k, v)| {
812877
assert_eq!(*v, *k * 2);
813878
observed |= (1 << *k);
814879
}
@@ -885,6 +950,7 @@ mod test_set {
885950
use super::*;
886951
use container::{Container, Map, Set};
887952
use vec;
953+
use uint;
888954

889955
#[test]
890956
fn test_disjoint() {
@@ -937,6 +1003,19 @@ mod test_set {
9371003
assert!(b.is_superset(&a));
9381004
}
9391005

1006+
#[test]
1007+
fn test_iterate() {
1008+
let mut a = HashSet::new();
1009+
for uint::range(0, 32) |i| {
1010+
assert!(a.insert(i));
1011+
}
1012+
let mut observed = 0;
1013+
for a.iter().advance |k| {
1014+
observed |= (1 << *k);
1015+
}
1016+
assert_eq!(observed, 0xFFFF_FFFF);
1017+
}
1018+
9401019
#[test]
9411020
fn test_intersection() {
9421021
let mut a = HashSet::new();

src/libstd/to_str.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ use hash::Hash;
2323
use cmp::Eq;
2424
use old_iter::BaseIter;
2525
use vec::ImmutableVector;
26+
use iterator::IteratorUtil;
2627

2728
/// A generic trait for converting a value to a string
2829
pub trait ToStr {
@@ -56,7 +57,7 @@ impl<A:ToStr+Hash+Eq, B:ToStr+Hash+Eq> ToStr for HashMap<A, B> {
5657
#[inline]
5758
fn to_str(&self) -> ~str {
5859
let mut (acc, first) = (~"{", true);
59-
for self.each |key, value| {
60+
for self.iter().advance |(key, value)| {
6061
if first {
6162
first = false;
6263
}
@@ -76,7 +77,7 @@ impl<A:ToStr+Hash+Eq> ToStr for HashSet<A> {
7677
#[inline]
7778
fn to_str(&self) -> ~str {
7879
let mut (acc, first) = (~"{", true);
79-
for self.each |element| {
80+
for self.iter().advance |element| {
8081
if first {
8182
first = false;
8283
}

0 commit comments

Comments
 (0)