4 releases
Uses old Rust 2015
0.1.3 | Jan 17, 2017 |
---|---|
0.1.2 | Jan 17, 2017 |
0.1.1 | Jan 17, 2017 |
0.1.0 | Jan 17, 2017 |
#2024 in Data structures
108 downloads per month
41KB
844 lines
multi_mut
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.
How to use
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 inOption
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 inOption
triple_mut(key, key, key)
Returns a triple of mutable references and panics if the keys don't exist.multi_mut()
anditer_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.
How to use 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");