Skip to content

Commit d8b299d

Browse files
committed
auto merge of #8293 : dim-an/rust/trie-iterator, r=thestinger
Closes #5506.
2 parents 2d1eb19 + 28165d5 commit d8b299d

File tree

1 file changed

+94
-0
lines changed

1 file changed

+94
-0
lines changed

src/libstd/trie.rs

+94
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ use prelude::*;
1414
use iterator::{IteratorUtil, FromIterator, Extendable};
1515
use uint;
1616
use util::{swap, replace};
17+
use vec;
1718

1819
// FIXME: #5244: need to manually update the TrieNode constructor
1920
static SHIFT: uint = 4;
@@ -146,6 +147,15 @@ impl<T> TrieMap<T> {
146147
pub fn each_value_reverse(&self, f: &fn(&T) -> bool) -> bool {
147148
self.each_reverse(|_, v| f(v))
148149
}
150+
151+
/// Get an iterator over the key-value pairs in the map
152+
pub fn iter<'a>(&'a self) -> TrieMapIterator<'a, T> {
153+
TrieMapIterator {
154+
stack: ~[self.root.children.iter()],
155+
remaining_min: self.length,
156+
remaining_max: self.length
157+
}
158+
}
149159
}
150160

151161
impl<T, Iter: Iterator<(uint, T)>> FromIterator<(uint, T), Iter> for TrieMap<T> {
@@ -217,6 +227,12 @@ impl TrieSet {
217227
pub fn each_reverse(&self, f: &fn(&uint) -> bool) -> bool {
218228
self.map.each_key_reverse(f)
219229
}
230+
231+
/// Get an iterator over the values in the set
232+
#[inline]
233+
pub fn iter<'a>(&'a self) -> TrieSetIterator<'a> {
234+
TrieSetIterator{iter: self.map.iter()}
235+
}
220236
}
221237

222238
impl<Iter: Iterator<uint>> FromIterator<uint, Iter> for TrieSet {
@@ -366,6 +382,61 @@ fn remove<T>(count: &mut uint, child: &mut Child<T>, key: uint,
366382
return ret;
367383
}
368384

385+
/// Forward iterator over a map
386+
pub struct TrieMapIterator<'self, T> {
387+
priv stack: ~[vec::VecIterator<'self, Child<T>>],
388+
priv remaining_min: uint,
389+
priv remaining_max: uint
390+
}
391+
392+
impl<'self, T> Iterator<(uint, &'self T)> for TrieMapIterator<'self, T> {
393+
fn next(&mut self) -> Option<(uint, &'self T)> {
394+
while !self.stack.is_empty() {
395+
match self.stack[self.stack.len() - 1].next() {
396+
None => {
397+
self.stack.pop();
398+
}
399+
Some(ref child) => {
400+
match **child {
401+
Internal(ref node) => {
402+
self.stack.push(node.children.iter());
403+
}
404+
External(key, ref value) => {
405+
self.remaining_max -= 1;
406+
if self.remaining_min > 0 {
407+
self.remaining_min -= 1;
408+
}
409+
return Some((key, value));
410+
}
411+
Nothing => {}
412+
}
413+
}
414+
}
415+
}
416+
return None;
417+
}
418+
419+
#[inline]
420+
fn size_hint(&self) -> (uint, Option<uint>) {
421+
(self.remaining_min, Some(self.remaining_max))
422+
}
423+
}
424+
425+
/// Forward iterator over a set
426+
pub struct TrieSetIterator<'self> {
427+
priv iter: TrieMapIterator<'self, ()>
428+
}
429+
430+
impl<'self> Iterator<uint> for TrieSetIterator<'self> {
431+
fn next(&mut self) -> Option<uint> {
432+
do self.iter.next().map |&(key, _)| { key }
433+
}
434+
435+
fn size_hint(&self) -> (uint, Option<uint>) {
436+
self.iter.size_hint()
437+
}
438+
}
439+
369440
#[cfg(test)]
370441
pub fn check_integrity<T>(trie: &TrieNode<T>) {
371442
assert!(trie.count != 0);
@@ -553,6 +624,29 @@ mod test_map {
553624
assert_eq!(map.find(&k), Some(&v));
554625
}
555626
}
627+
628+
#[test]
629+
fn test_iteration() {
630+
let empty_map : TrieMap<uint> = TrieMap::new();
631+
assert_eq!(empty_map.iter().next(), None);
632+
633+
let first = uint::max_value - 10000;
634+
let last = uint::max_value;
635+
636+
let mut map = TrieMap::new();
637+
do uint::range_rev(last, first) |x| {
638+
map.insert(x, x / 2);
639+
true
640+
};
641+
642+
let mut i = 0;
643+
for (k, &v) in map.iter() {
644+
assert_eq!(k, first + i);
645+
assert_eq!(v, k / 2);
646+
i += 1;
647+
}
648+
assert_eq!(i, last - first);
649+
}
556650
}
557651

558652
#[cfg(test)]

0 commit comments

Comments
 (0)