diff options
| author | bors <bors@rust-lang.org> | 2013-03-25 22:24:57 -0700 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2013-03-25 22:24:57 -0700 |
| commit | 74815249787076f0e3cd9c8dc72553f73e612856 (patch) | |
| tree | c4a21aa3f8b47b13b47c632ea93f3368ed4a5c28 /src/libstd | |
| parent | 47ddb59b802faa25b733416caf3d1b5588ab60a3 (diff) | |
| parent | e8bf0a4a49405cfde21910af889d626fbdd5bd52 (diff) | |
| download | rust-74815249787076f0e3cd9c8dc72553f73e612856.tar.gz rust-74815249787076f0e3cd9c8dc72553f73e612856.zip | |
auto merge of #5528 : thestinger/rust/find_mut, r=brson
This currently requires workarounds for the borrow checker not being flow-sensitive for `LinearMap` and `TrieMap`, but it can already be expressed for `TreeMap` and `SmallIntMap` without that.
Diffstat (limited to 'src/libstd')
| -rw-r--r-- | src/libstd/smallintmap.rs | 30 | ||||
| -rw-r--r-- | src/libstd/treemap.rs | 37 |
2 files changed, 62 insertions, 5 deletions
diff --git a/src/libstd/smallintmap.rs b/src/libstd/smallintmap.rs index a559e7540d4..4ad8d38b072 100644 --- a/src/libstd/smallintmap.rs +++ b/src/libstd/smallintmap.rs @@ -86,7 +86,7 @@ impl<V> Map<uint, V> for SmallIntMap<V> { self.each(|&(_, v)| blk(v)) } - /// Visit all key-value pairs in order + /// Iterate over the map and mutate the contained values fn mutate_values(&mut self, it: &fn(&uint, &'self mut V) -> bool) { for uint::range(0, self.v.len()) |i| { match self.v[i] { @@ -96,7 +96,7 @@ impl<V> Map<uint, V> for SmallIntMap<V> { } } - /// Iterate over the map and mutate the contained values + /// Return a reference to the value corresponding to the key fn find(&self, key: &uint) -> Option<&'self V> { if *key < self.v.len() { match self.v[*key] { @@ -108,6 +108,18 @@ impl<V> Map<uint, V> for SmallIntMap<V> { } } + /// Return a mutable reference to the value corresponding to the key + fn find_mut(&mut self, key: &uint) -> Option<&'self mut V> { + if *key < self.v.len() { + match self.v[*key] { + Some(ref mut value) => Some(value), + None => None + } + } else { + None + } + } + /// Insert a key-value pair into the map. An existing value for a /// key is replaced by the new value. Return true if the key did /// not already exist in the map. @@ -160,6 +172,20 @@ pub impl<V:Copy> SmallIntMap<V> { #[cfg(test)] mod tests { use super::SmallIntMap; + use core::prelude::*; + + #[test] + fn test_find_mut() { + let mut m = SmallIntMap::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_len() { diff --git a/src/libstd/treemap.rs b/src/libstd/treemap.rs index 1da1edae7d2..fccf58ddb6f 100644 --- a/src/libstd/treemap.rs +++ b/src/libstd/treemap.rs @@ -135,7 +135,7 @@ impl<K: TotalOrd, V> Map<K, V> for TreeMap<K, V> { mutate_values(&mut self.root, f); } - /// Return the value corresponding to the key in the map + /// Return a reference to the value corresponding to the key fn find(&self, key: &K) -> Option<&'self V> { let mut current: &'self Option<~TreeNode<K, V>> = &self.root; loop { @@ -152,6 +152,12 @@ impl<K: TotalOrd, V> Map<K, V> for TreeMap<K, V> { } } + /// Return a mutable reference to the value corresponding to the key + #[inline(always)] + fn find_mut(&mut self, key: &K) -> Option<&'self mut V> { + find_mut(&mut self.root, key) + } + /// Insert a key-value pair into the map. An existing value for a /// key is replaced by the new value. Return true if the key did /// not already exist in the map. @@ -584,8 +590,20 @@ fn split<K: TotalOrd, V>(node: &mut ~TreeNode<K, V>) { } } -fn insert<K: TotalOrd, V>(node: &mut Option<~TreeNode<K, V>>, key: K, - value: V) -> bool { +fn find_mut<K: TotalOrd, V>(node: &'r mut Option<~TreeNode<K, V>>, key: &K) -> Option<&'r mut V> { + match *node { + Some(ref mut x) => { + match key.cmp(&x.key) { + Less => find_mut(&mut x.left, key), + Greater => find_mut(&mut x.right, key), + Equal => Some(&mut x.value), + } + } + None => None + } +} + +fn insert<K: TotalOrd, V>(node: &mut Option<~TreeNode<K, V>>, key: K, value: V) -> bool { match *node { Some(ref mut save) => { match key.cmp(&save.key) { @@ -717,6 +735,19 @@ mod test_treemap { } #[test] + fn test_find_mut() { + let mut m = TreeMap::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 insert_replace() { let mut m = TreeMap::new(); fail_unless!(m.insert(5, 2)); |
