| Crates.io | multi_mut |
| lib.rs | multi_mut |
| version | 0.1.3 |
| created_at | 2017-01-17 02:42:19.825987+00 |
| updated_at | 2017-01-17 04:01:25.015012+00 |
| description | Methods on HashMap and BTreeMap for safely getting multiple mutable references to the contained values. |
| homepage | |
| repository | https://github.com/golddranks/multi_mut |
| max_upload_size | |
| id | 8104 |
| size | 41,331 |
A bunch of extension methods on HashMap and BTreeMap that provide a safe API for getting multiple mutable references to values contained in them.
Runtime checks are done to prevent mutable aliasing.
Add to Cargo.toml::
[dependencies]
multi_mut = "0.1"
Bring the extension trait to the scope in your code:
extern crate multi_mut;
use multi_mut::HashMapMultiMut;
or
extern crate multi_mut;
use multi_mut::BTreeMapMultiMut;
You can now have more than one mutable reference to your HashMap or BTreeMap safely!
let (one, two) = map.get_pair_mut("key_one", "key_two").unwrap();
assert_eq!(one, "value_one");
assert_eq!(two, "value_two");
one.push_str("_edited");
two.push_str("_edited");
assert_eq!(one, "value_one_edited");
assert_eq!(two, "value_two_edited");
Quick & dirty list of available functions:
get_pair_mut(key, key) Returns a pair of mutable references wrapped in Optionpair_mut(key, key) Returns a pair of mutable references and panics if the keys don't exist.get_triple_mut(key, key, key)Returns a triple of mutable references wrapped in Optiontriple_mut(key, key, key) Returns a triple of mutable references and panics if the keys don't exist.multi_mut() and iter_multi_mut() return arbitrary number of mutable references. Check out the example below.To prevent mutable aliasing, all functions will panic if the input keys aren't unique. None of the functions allocate.
multi_mut() and iter_multi_mut() perform a linear search over a buffer of pointers every time a mutable reference
is pulled out of the HashMap/BTreeMap. In practice, this is fast enough.
multi_mut() and iter_multi_mut()multi_mut() and iter_multi_mut() need a mutable buffer to keep track of existing references to prevent mutable aliasing.
See the line let mut buffer = [std::ptr::null(); 3]; in the example. The size of the buffer determines how many values you can
pull out of the underlying HashMap/BTreeMap.
The difference between the two methods is that multi_mut() returns a wrapper which can be used to fetch mutable references
from HashMap/BTreeMap using the get_mut(&K) -> Option<&mut V> or mut_ref(&K) -> &mut V (this panics if the key doesn't exist) methods,
whereas iter_multi_mut() requires a list of keys up front, and then returns an iterator that spews out mutable references.
An example of multi_mut():
let mut buffer = [std::ptr::null(); 3];
let mut wrapper = map.multi_mut(&mut buffer);
let one = wrapper.get_mut("key_one").unwrap();
let two = wrapper.get_mut("key_two").unwrap();
let three = wrapper.get_mut("key_three").unwrap();
assert_eq!(one, "value_one");
assert_eq!(two, "value_two");
assert_eq!(three, "value_three");
one.push_str("_edited");
two.push_str("_edited");
three.push_str("_edited");
assert_eq!(one, "value_one_edited");
assert_eq!(two, "value_two_edited");
assert_eq!(three, "value_three_edited");
An example of iter_multi_mut():
let mut buffer = [std::ptr::null(); 3];
let keys = ["key_one", "key_two", "key_three"];
let mut wrapper = map.iter_multi_mut(&keys, &mut buffer);
let one = wrapper.next().unwrap();
let two = wrapper.next().unwrap();
let three = wrapper.next().unwrap();
assert_eq!(one, "value_one");
assert_eq!(two, "value_two");
assert_eq!(three, "value_three");
one.push_str("_edited");
two.push_str("_edited");
three.push_str("_edited");
assert_eq!(one, "value_one_edited");
assert_eq!(two, "value_two_edited");
assert_eq!(three, "value_three_edited");