Skip to content

Commit 080d498

Browse files
blake2-ppcthestinger
blake2-ppc
authored andcommitted
std::hashmap: Implement external iterator for HashMap and HashSet
1 parent 3b126e4 commit 080d498

File tree

1 file changed

+79
-12
lines changed

1 file changed

+79
-12
lines changed

src/libstd/hashmap.rs

Lines changed: 79 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,13 @@ use cmp::{Eq, Equiv};
2020
use hash::Hash;
2121
use old_iter::BaseIter;
2222
use old_iter;
23-
use iterator::IteratorUtil;
23+
use iterator::{Iterator, IteratorUtil};
2424
use option::{None, Option, Some};
2525
use rand::RngUtil;
2626
use rand;
2727
use uint;
2828
use vec;
29-
use vec::ImmutableVector;
29+
use vec::{ImmutableVector, MutableVector};
3030
use kinds::Copy;
3131
use util::{replace, unreachable};
3232

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

312312
/// Visit all key-value pairs
313313
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;
314+
self.iter().advance(|(k, v)| blk(k, v))
322315
}
323316

324317
/// Visit all keys
325318
fn each_key(&self, blk: &fn(k: &K) -> bool) -> bool {
326-
self.each(|k, _| blk(k))
319+
self.iter().advance(|(k, _)| blk(k))
327320
}
328321

329322
/// Visit all values
330323
fn each_value<'a>(&'a self, blk: &fn(v: &'a V) -> bool) -> bool {
331-
self.each(|_, v| blk(v))
324+
self.iter().advance(|(_, v)| blk(v))
332325
}
333326

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

529535
impl<K: Hash + Eq, V: Copy> HashMap<K, V> {
@@ -555,6 +561,61 @@ impl<K:Hash + Eq,V:Eq> Eq for HashMap<K, V> {
555561
fn ne(&self, other: &HashMap<K, V>) -> bool { !self.eq(other) }
556562
}
557563

564+
/// HashMap iterator
565+
pub struct HashMapIterator<'self, K, V> {
566+
priv iter: vec::VecIterator<'self, Option<Bucket<K, V>>>,
567+
}
568+
569+
/// HashMap mutable values iterator
570+
pub struct HashMapMutIterator<'self, K, V> {
571+
priv iter: vec::VecMutIterator<'self, Option<Bucket<K, V>>>,
572+
}
573+
574+
/// HashSet iterator
575+
pub struct HashSetIterator<'self, K> {
576+
priv iter: vec::VecIterator<'self, Option<Bucket<K, ()>>>,
577+
}
578+
579+
impl<'self, K, V> Iterator<(&'self K, &'self V)> for HashMapIterator<'self, K, V> {
580+
#[inline]
581+
fn next(&mut self) -> Option<(&'self K, &'self V)> {
582+
for self.iter.advance |elt| {
583+
match elt {
584+
&Some(ref bucket) => return Some((&bucket.key, &bucket.value)),
585+
&None => {},
586+
}
587+
}
588+
None
589+
}
590+
}
591+
592+
impl<'self, K, V> Iterator<(&'self K, &'self mut V)> for HashMapMutIterator<'self, K, V> {
593+
#[inline]
594+
fn next(&mut self) -> Option<(&'self K, &'self mut V)> {
595+
for self.iter.advance |elt| {
596+
match elt {
597+
&Some(ref mut bucket) => return Some((&bucket.key, &mut bucket.value)),
598+
&None => {},
599+
}
600+
}
601+
None
602+
}
603+
}
604+
605+
impl<'self, K> Iterator<&'self K> for HashSetIterator<'self, K> {
606+
#[inline]
607+
fn next(&mut self) -> Option<&'self K> {
608+
for self.iter.advance |elt| {
609+
match elt {
610+
&Some(ref bucket) => return Some(&bucket.key),
611+
&None => {},
612+
}
613+
}
614+
None
615+
}
616+
}
617+
618+
558619
/// An implementation of a hash set using the underlying representation of a
559620
/// HashMap where the value is (). As with the `HashMap` type, a `HashSet`
560621
/// requires that the elements implement the `Eq` and `Hash` traits.
@@ -664,6 +725,12 @@ impl<T:Hash + Eq> HashSet<T> {
664725
pub fn contains_equiv<Q:Hash + Equiv<T>>(&self, value: &Q) -> bool {
665726
self.map.contains_key_equiv(value)
666727
}
728+
729+
/// An iterator visiting all elements in arbitrary order.
730+
/// Iterator element type is &'a T.
731+
pub fn iter<'a>(&'a self) -> HashSetIterator<'a, T> {
732+
HashSetIterator { iter: self.map.buckets.iter() }
733+
}
667734
}
668735

669736
#[cfg(test)]

0 commit comments

Comments
 (0)