diff options
| author | Daniel Micay <danielmicay@gmail.com> | 2013-03-24 20:30:35 -0400 |
|---|---|---|
| committer | Daniel Micay <danielmicay@gmail.com> | 2013-03-24 20:30:35 -0400 |
| commit | 89e2578a9d1cd18270b7148a5d5d6b8bee051ac5 (patch) | |
| tree | 6ab22eb46606e4989b738d38ecd17268b97575e5 | |
| parent | d77433386be3d5afa201cfd40dbaaa4d20dbbd80 (diff) | |
trie: add find_mut method
| -rw-r--r-- | src/libcore/trie.rs | 33 |
1 files changed, 32 insertions, 1 deletions
diff --git a/src/libcore/trie.rs b/src/libcore/trie.rs index 40ef5fee47a..007bafcd03d 100644 --- a/src/libcore/trie.rs +++ b/src/libcore/trie.rs @@ -90,7 +90,7 @@ impl<T> Map<uint, T> for TrieMap<T> { self.root.mutate_values(f); } - /// Return the value corresponding to the key in the map + /// Return a reference to the value corresponding to the key #[inline(hint)] fn find(&self, key: &uint) -> Option<&'self T> { let mut node: &'self TrieNode<T> = &self.root; @@ -153,6 +153,12 @@ pub impl<T> TrieMap<T> { fn each_value_reverse(&self, f: &fn(&T) -> bool) { self.each_reverse(|&(_, v)| f(v)) } + + /// Return a mutable reference to the value corresponding to the key + #[inline(always)] + fn find_mut(&mut self, key: &uint) -> Option<&'self mut T> { + find_mut(&mut self.root.children[chunk(*key, 0)], *key, 1) + } } pub struct TrieSet { @@ -276,6 +282,17 @@ fn chunk(n: uint, idx: uint) -> uint { (n >> sh) & MASK } +fn find_mut<T>(child: &'r mut Child<T>, key: uint, idx: uint) -> Option<&'r mut T> { + unsafe { // FIXME(#4903)---requires flow-sensitive borrow checker + (match *child { + External(_, ref value) => Some(cast::transmute_mut(value)), + Internal(ref x) => find_mut(cast::transmute_mut(&x.children[chunk(key, idx)]), + key, idx + 1), + Nothing => None + }).map_consume(|x| cast::transmute_mut_region(x)) + } +} + fn insert<T>(count: &mut uint, child: &mut Child<T>, key: uint, value: T, idx: uint) -> bool { let mut tmp = Nothing; @@ -357,9 +374,23 @@ pub fn check_integrity<T>(trie: &TrieNode<T>) { #[cfg(test)] mod tests { use super::*; + use core::option::{Some, None}; use uint; #[test] + fn test_find_mut() { + let mut m = TrieMap::new(); + fail_unless!(m.insert(1, 12)); + fail_unless!(m.insert(2, 8)); + fail_unless!(m.insert(5, 14)); + let new = 100; + match m.find_mut(&5) { + None => fail!(), Some(x) => *x = new + } + assert_eq!(m.find(&5), Some(&new)); + } + + #[test] fn test_step() { let mut trie = TrieMap::new(); let n = 300; |
