|
18 | 18 | //! and memory penalty. Notably, indexing by `K2` requires two HashMap lookups. |
19 | 19 | //! |
20 | 20 | //! ``` |
21 | | -//! # extern crate multi_map; |
| 21 | +//! extern crate multi_map; |
22 | 22 | //! use multi_map::MultiMap; |
| 23 | +//! |
23 | 24 | //! # fn main() { |
24 | 25 | //! #[derive(Hash,Clone,PartialEq,Eq)] |
25 | 26 | //! enum ThingIndex { |
26 | 27 | //! IndexOne, |
27 | 28 | //! IndexTwo, |
28 | 29 | //! IndexThree, |
29 | 30 | //! }; |
| 31 | +//! |
30 | 32 | //! let mut map = MultiMap::new(); |
31 | 33 | //! map.insert("One", ThingIndex::IndexOne, 1); |
32 | 34 | //! map.insert("Two", ThingIndex::IndexTwo, 2); |
| 35 | +//! |
33 | 36 | //! assert!(*map.get_alt(&ThingIndex::IndexOne).unwrap() == 1); |
34 | 37 | //! assert!(*map.get(&"Two").unwrap() == 2); |
35 | 38 | //! assert!(map.remove_alt(&ThingIndex::IndexTwo).unwrap() == 2); |
@@ -64,6 +67,16 @@ impl<K1: Eq + Hash + Clone, K2: Eq + Hash + Clone, V> MultiMap<K1, K2, V> { |
64 | 67 | } |
65 | 68 | } |
66 | 69 |
|
| 70 | + /// Creates an empty MultiMap with the specified capacity. |
| 71 | + /// |
| 72 | + /// The multi map will be able to hold at least `capacity` elements without reallocating. If `capacity` is 0, the multi map will not allocate. |
| 73 | + pub fn with_capacity(capacity: usize) -> MultiMap<K1, K2, V> { |
| 74 | + MultiMap { |
| 75 | + value_map: HashMap::with_capacity(capacity), |
| 76 | + key_map: HashMap::with_capacity(capacity), |
| 77 | + } |
| 78 | + } |
| 79 | + |
67 | 80 | /// Insert an item into the MultiMap. You must supply both keys to insert |
68 | 81 | /// an item. The keys cannot be modified at a later date, so if you only |
69 | 82 | /// have one key at this time, use a placeholder value for the second key |
@@ -157,6 +170,50 @@ impl<K1: Eq + Hash + Clone, K2: Eq + Hash + Clone, V> MultiMap<K1, K2, V> { |
157 | 170 | } |
158 | 171 | } |
159 | 172 |
|
| 173 | +#[macro_export] |
| 174 | +/// Create a MultiMap from a list of key-value tuples |
| 175 | +/// |
| 176 | +/// ## Example |
| 177 | +/// |
| 178 | +/// ``` |
| 179 | +/// #[macro_use] |
| 180 | +/// extern crate multi_map; |
| 181 | +/// use multi_map::MultiMap; |
| 182 | +/// |
| 183 | +/// # fn main() { |
| 184 | +/// #[derive(Hash,Clone,PartialEq,Eq)] |
| 185 | +/// enum ThingIndex { |
| 186 | +/// IndexOne, |
| 187 | +/// IndexTwo, |
| 188 | +/// IndexThree, |
| 189 | +/// }; |
| 190 | +/// |
| 191 | +/// let map = multimap!{ |
| 192 | +/// "One", ThingIndex::IndexOne => 1, |
| 193 | +/// "Two", ThingIndex::IndexTwo => 2, |
| 194 | +/// }; |
| 195 | +/// |
| 196 | +/// assert!(*map.get_alt(&ThingIndex::IndexOne).unwrap() == 1); |
| 197 | +/// assert!(*map.get(&"Two").unwrap() == 2); |
| 198 | +/// # } |
| 199 | +/// ``` |
| 200 | +macro_rules! multimap { |
| 201 | + (@single $($x:tt)*) => (()); |
| 202 | + (@count $($rest:expr),*) => (<[()]>::len(&[$(multimap!(@single $rest)),*])); |
| 203 | + |
| 204 | + ($($key1:expr, $key2:expr => $value:expr,)+) => { multimap!($($key1, $key2 => $value),+) }; |
| 205 | + ($($key1:expr, $key2:expr => $value:expr),*) => { |
| 206 | + { |
| 207 | + let _cap = multimap!(@count $($key1),*); |
| 208 | + let mut _map = MultiMap::with_capacity(_cap); |
| 209 | + $( |
| 210 | + _map.insert($key1, $key2, $value); |
| 211 | + )* |
| 212 | + _map |
| 213 | + } |
| 214 | + }; |
| 215 | +} |
| 216 | + |
160 | 217 | mod test { |
161 | 218 |
|
162 | 219 | #[test] |
@@ -195,6 +252,32 @@ mod test { |
195 | 252 | assert!(*map.get(&2).unwrap() == String::from("Zwei!")); |
196 | 253 | assert!(map.get_alt(&"Three") == None); |
197 | 254 | assert!(map.get(&3) == None); |
| 255 | + } |
| 256 | + |
| 257 | + #[test] |
| 258 | + fn macro_test() { |
| 259 | + use ::MultiMap; |
| 260 | + |
| 261 | + let _: MultiMap<i32, &str, String> = multimap!{}; |
| 262 | + |
| 263 | + multimap!{ |
| 264 | + 1, "One" => String::from("Eins"), |
| 265 | + }; |
| 266 | + |
| 267 | + multimap!{ |
| 268 | + 1, "One" => String::from("Eins") |
| 269 | + }; |
| 270 | + |
| 271 | + multimap!{ |
| 272 | + 1, "One" => String::from("Eins"), |
| 273 | + 2, "Two" => String::from("Zwei"), |
| 274 | + 3, "Three" => String::from("Drei"), |
| 275 | + }; |
198 | 276 |
|
| 277 | + multimap!{ |
| 278 | + 1, "One" => String::from("Eins"), |
| 279 | + 2, "Two" => String::from("Zwei"), |
| 280 | + 3, "Three" => String::from("Drei") |
| 281 | + }; |
199 | 282 | } |
200 | 283 | } |
0 commit comments