Crates.io | multi_mut |
lib.rs | multi_mut |
version | 0.1.3 |
source | src |
created_at | 2017-01-17 02:42:19.825987 |
updated_at | 2017-01-17 04:01:25.015012 |
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 Option
pair_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 Option
triple_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");