diff --git a/src/libcore/trie.rs b/src/libcore/trie.rs index c8faccf28f255..bb9eb1e6e6907 100644 --- a/src/libcore/trie.rs +++ b/src/libcore/trie.rs @@ -32,7 +32,7 @@ impl BaseIter<(uint, &T)> for TrieMap { /// Visit all key-value pairs in order #[inline(always)] pure fn each(&self, f: fn(&(uint, &self/T)) -> bool) { - self.root.each(f) + self.root.each(f); } #[inline(always)] pure fn size_hint(&self) -> Option { Some(self.len()) } @@ -42,7 +42,7 @@ impl ReverseIter<(uint, &T)> for TrieMap { /// Visit all key-value pairs in reverse order #[inline(always)] pure fn each_reverse(&self, f: fn(&(uint, &self/T)) -> bool) { - self.root.each_reverse(f) + self.root.each_reverse(f); } } @@ -149,7 +149,7 @@ impl TrieMap { /// Iterate over the map and mutate the contained values fn mutate_values(&mut self, f: fn(uint, &mut T) -> bool) { - self.root.mutate_values(f) + self.root.mutate_values(f); } } @@ -217,34 +217,39 @@ impl TrieNode { } impl TrieNode { - pure fn each(&self, f: fn(&(uint, &self/T)) -> bool) { + pure fn each(&self, f: fn(&(uint, &self/T)) -> bool) -> bool { for uint::range(0, self.children.len()) |idx| { match self.children[idx] { - Internal(ref x) => x.each(f), - External(k, ref v) => if !f(&(k, v)) { return }, + Internal(ref x) => if !x.each(f) { return false }, + External(k, ref v) => if !f(&(k, v)) { return false }, Nothing => () } } + true } - pure fn each_reverse(&self, f: fn(&(uint, &self/T)) -> bool) { + pure fn each_reverse(&self, f: fn(&(uint, &self/T)) -> bool) -> bool { for uint::range_rev(self.children.len(), 0) |idx| { match self.children[idx - 1] { - Internal(ref x) => x.each(f), - External(k, ref v) => if !f(&(k, v)) { return }, + Internal(ref x) => if !x.each_reverse(f) { return false }, + External(k, ref v) => if !f(&(k, v)) { return false }, Nothing => () } } + true } - fn mutate_values(&mut self, f: fn(uint, &mut T) -> bool) { + fn mutate_values(&mut self, f: fn(uint, &mut T) -> bool) -> bool { for vec::each_mut(self.children) |child| { match *child { - Internal(ref mut x) => x.mutate_values(f), - External(k, ref mut v) => if !f(k, v) { return }, + Internal(ref mut x) => if !x.mutate_values(f) { + return false + }, + External(k, ref mut v) => if !f(k, v) { return false }, Nothing => () } } + true } } @@ -366,4 +371,78 @@ mod tests { check_integrity(&trie.root); } } + + #[test] + fn test_each() { + let mut m = TrieMap::new(); + + assert m.insert(3, 6); + assert m.insert(0, 0); + assert m.insert(4, 8); + assert m.insert(2, 4); + assert m.insert(1, 2); + + let mut n = 0; + for m.each |&(k, v)| { + assert k == n; + assert *v == n * 2; + n += 1; + } + } + + #[test] + fn test_each_break() { + let mut m = TrieMap::new(); + + for uint::range_rev(uint::max_value, uint::max_value - 10000) |x| { + m.insert(x, x / 2); + } + + let mut n = uint::max_value - 9999; + for m.each |&(k, v)| { + if n == uint::max_value - 5000 { break } + assert n < uint::max_value - 5000; + + assert k == n; + assert *v == n / 2; + n += 1; + } + } + + #[test] + fn test_each_reverse() { + let mut m = TrieMap::new(); + + assert m.insert(3, 6); + assert m.insert(0, 0); + assert m.insert(4, 8); + assert m.insert(2, 4); + assert m.insert(1, 2); + + let mut n = 4; + for m.each_reverse |&(k, v)| { + assert k == n; + assert *v == n * 2; + n -= 1; + } + } + + #[test] + fn test_each_reverse_break() { + let mut m = TrieMap::new(); + + for uint::range_rev(uint::max_value, uint::max_value - 10000) |x| { + m.insert(x, x / 2); + } + + let mut n = uint::max_value; + for m.each_reverse |&(k, v)| { + if n == uint::max_value - 5000 { break } + assert n > uint::max_value - 5000; + + assert k == n; + assert *v == n / 2; + n -= 1; + } + } }