double_map/map.rs
1#[cfg(test)]
2mod tests_double_map;
3
4use core::borrow::Borrow;
5use core::convert::From;
6use core::default::Default;
7use core::fmt::{self, Debug};
8use core::hash::{BuildHasher, Hash};
9use core::hint::unreachable_unchecked;
10use core::iter::{Extend, FromIterator, FusedIterator};
11use core::mem;
12use core::ops::Index;
13use std::collections::{hash_map, HashMap, TryReserveError};
14
15/// A hash map with double keys implemented as wrapper above two
16/// [`HashMaps`](`std::collections::HashMap`).
17///
18/// Internally, two [`HashMap`](`std::collections::HashMap`) are created. One of type
19/// `HashMap<K1, (K2, V)>` to hold the `(K2, V)` tuple, and second one of type
20/// `HashMap<K2, K1>` just for holding the primary key of type `K1`.
21/// We hold the `(K2, V)` tuple inside first `Hashmap` for synchronization purpose,
22/// so that we can organize checking that both primary key of type `K1` and the
23/// secondary key is of type `K2` refer to the same value, and so on.
24/// Keys may be the same or different type.
25///
26/// By default, [`DHashMap`] as [`HashMap`](`std::collections::HashMap`)
27/// uses a hashing algorithm selected to provide
28/// resistance against HashDoS attacks. The algorithm is randomly seeded, and a
29/// reasonable best-effort is made to generate this seed from a high quality,
30/// secure source of randomness provided by the host without blocking the
31/// program. Because of this, the randomness of the seed depends on the output
32/// quality of the system's random number generator when the seed is created.
33/// In particular, seeds generated when the system's entropy pool is abnormally
34/// low such as during system boot may be of a lower quality.
35///
36/// The default hashing algorithm, like in [`HashMap`](`std::collections::HashMap`),
37/// is currently SipHash 1-3, though this is
38/// subject to change at any point in the future. While its performance is very
39/// competitive for medium sized keys, other hashing algorithms will outperform
40/// it for small keys like integers as well as large keys like long
41/// strings, though those algorithms will typically *not* protect against
42/// attacks such as HashDoS.
43///
44/// The hashing algorithm can be replaced on a per-[`DHashMap`] basis using the
45/// [`default`](`std::default::Default::default`), [`with_hasher`](`DHashMap::with_hasher`),
46/// and [`with_capacity_and_hasher`](`DHashMap::with_capacity_and_hasher`) methods.
47/// There are many alternative [hashing algorithms available on crates.io].
48///
49/// It is required that the keys implement the [`Eq`] and
50/// [`Hash`](`core::hash::Hash`) traits, although
51/// this can frequently be achieved by using `#[derive(PartialEq, Eq, Hash)]`.
52/// If you implement these yourself, it is important that the following
53/// property holds:
54///
55/// ```text
56/// k1 == k2 -> hash(k1) == hash(k2)
57/// ```
58///
59/// In other words, if two keys are equal, their hashes must be equal.
60///
61/// It is a logic error for a key to be modified in such a way that the key's
62/// hash, as determined by the [`Hash`] trait, or its equality, as determined by
63/// the [`Eq`] trait, changes while it is in the map. This is normally only
64/// possible through [`Cell`](`std::cell::Cell`), [`RefCell`](`std::cell::RefCell`),
65/// global state, I/O, or unsafe code.
66/// The behavior resulting from such a logic error is not specified, but will
67/// not result in undefined behavior. This could include panics, incorrect results,
68/// aborts, memory leaks, and non-termination.
69///
70/// [hashing algorithms available on crates.io]: https://crates.io/keywords/hasher
71
72#[derive(Clone, Debug)]
73pub struct DHashMap<K1, K2, V, S = hash_map::RandomState> {
74 value_map: HashMap<K1, (K2, V), S>,
75 key_map: HashMap<K2, K1, S>,
76}
77
78impl<K1, K2, V> DHashMap<K1, K2, V, hash_map::RandomState> {
79 /// Creates a new empty [`DHashMap`]s with [`RandomState`](std::collections::hash_map::RandomState)
80 /// type of hash builder to hash keys.
81 ///
82 /// The primary key is of type `K1` and the secondary key is of type `K2`.
83 /// The value is of type `V`.
84 ///
85 /// Internally, two [`HashMap`](`std::collections::HashMap`) are created. One of type
86 /// `HashMap<K1, (K2, V)>` to hold the `(K2, V)` tuple, and second one of type
87 /// `HashMap<K2, K1>` just for holding the primary key of type `K1`.
88 /// We hold the `(K2, V)` tuple inside first `Hashmap` for synchronization purpose,
89 /// so that we can organize checking both primary key of type `K1` and the
90 /// secondary key is of type `K2` refer to the same value, and so on.
91 ///
92 /// The hash map is initially created with a capacity of 0, so it will not allocate until
93 /// it is first inserted into.
94 ///
95 /// # Examples
96 ///
97 /// ```
98 /// use double_map::DHashMap;
99 /// let mut map: DHashMap<u32, &str, i32> = DHashMap::new();
100 ///
101 /// // The created DHashMap holds none elements
102 /// assert_eq!(map.len(), 0);
103 ///
104 /// // The created DHashMap also doesn't allocate memory
105 /// assert_eq!(map.capacity(), 0);
106 ///
107 /// // Now we insert element inside created DHashMap
108 /// map.insert(1, "One", 1);
109 /// // We can see that the DHashMap holds 1 element
110 /// assert_eq!(map.len(), 1);
111 /// // And it also allocates some capacity (by default it starts from 3 elements)
112 /// assert!(map.capacity() > 1);
113 /// ```
114 #[inline]
115 #[must_use]
116 pub fn new() -> DHashMap<K1, K2, V, hash_map::RandomState> {
117 DHashMap {
118 value_map: HashMap::new(),
119 key_map: HashMap::new(),
120 }
121 }
122
123 /// Creates an empty [`DHashMap`] with the specified capacity.
124 ///
125 /// The hash map will be able to hold at least `capacity` elements without
126 /// reallocating. If `capacity` is 0, the hash map will not allocate.
127 ///
128 /// # Examples
129 ///
130 /// ```
131 /// use double_map::DHashMap;
132 /// let mut map: DHashMap<&str, i32, &str> = DHashMap::with_capacity(5);
133 ///
134 /// // The created DHashMap holds none elements
135 /// assert_eq!(map.len(), 0);
136 /// // But it can hold at least 5 elements without reallocating
137 /// let empty_map_capacity = map.capacity();
138 /// assert!(empty_map_capacity >= 5);
139 ///
140 /// // Now we insert some 5 elements inside created DHashMap
141 /// map.insert("One", 1, "a");
142 /// map.insert("Two", 2, "b");
143 /// map.insert("Three", 3, "c");
144 /// map.insert("Four", 4, "d");
145 /// map.insert("Five", 5, "e");
146 ///
147 /// // We can see that the DHashMap holds 5 elements
148 /// assert_eq!(map.len(), 5);
149 /// // But its capacity isn't changed
150 /// assert_eq!(map.capacity(), empty_map_capacity)
151 /// ```
152 #[inline]
153 #[must_use]
154 pub fn with_capacity(capacity: usize) -> DHashMap<K1, K2, V, hash_map::RandomState> {
155 DHashMap {
156 value_map: HashMap::with_capacity(capacity),
157 key_map: HashMap::with_capacity(capacity),
158 }
159 }
160}
161
162impl<K1, K2, V, S> DHashMap<K1, K2, V, S>
163where
164 S: Clone,
165{
166 /// Creates an empty [`DHashMap`] which will use the given hash builder to hash
167 /// keys.
168 ///
169 /// The created map has the default initial capacity, witch is equal to 0, so
170 /// it will not allocate until it is first inserted into.
171 ///
172 /// Warning: `hash_builder` is normally randomly generated, and
173 /// is designed to allow [`DHashMap`] to be resistant to attacks that
174 /// cause many collisions and very poor performance. Setting it
175 /// manually using this function can expose a DoS attack vector.
176 ///
177 /// The `hash_builder` passed should implement the [`BuildHasher`] trait for
178 /// the [`DHashMap`] to be useful, see its documentation for details.
179 /// It also should implement the [`Clone`] trait because we create two
180 /// [`HashMap`]s inside the [`DHashMap`], so that we need to
181 /// [`clone`](core::clone::Clone::clone) hash_builder for passing it inside
182 /// two inner `HashMaps`.
183 ///
184 /// # Examples
185 ///
186 /// ```
187 /// use double_map::DHashMap;
188 /// use std::collections::hash_map::RandomState;
189 ///
190 /// let s = RandomState::new();
191 /// let mut map = DHashMap::with_hasher(s);
192 ///
193 /// // The created DHashMap holds none elements
194 /// assert_eq!(map.len(), 0);
195 ///
196 /// // The created DHashMap also doesn't allocate memory
197 /// assert_eq!(map.capacity(), 0);
198 ///
199 /// // Now we insert elements inside created DHashMap
200 /// map.insert("One", 1, 2);
201 /// // We can see that the DHashMap holds 1 element
202 /// assert_eq!(map.len(), 1);
203 /// // And it also allocates some capacity (by default it starts from 3 elements)
204 /// assert!(map.capacity() > 1);
205 /// ```
206 #[inline]
207 pub fn with_hasher(hash_builder: S) -> DHashMap<K1, K2, V, S> {
208 DHashMap {
209 value_map: HashMap::with_hasher(hash_builder.clone()),
210 key_map: HashMap::with_hasher(hash_builder),
211 }
212 }
213
214 /// Creates an empty [`DHashMap`] with the specified capacity, using `hash_builder`
215 /// to hash the keys.
216 ///
217 /// The hash map will be able to hold at least `capacity` elements without
218 /// reallocating. If `capacity` is 0, the hash map will not allocate.
219 ///
220 /// Warning: `hash_builder` is normally randomly generated, and
221 /// is designed to allow HashMaps to be resistant to attacks that
222 /// cause many collisions and very poor performance. Setting it
223 /// manually using this function can expose a DoS attack vector.
224 ///
225 /// The `hash_builder` passed should implement the [`BuildHasher`] trait for
226 /// the [`DHashMap`] to be useful, see its documentation for details.
227 /// It also should implement the [`Clone`] trait because we create two
228 /// [`HashMap`]s inside the [`DHashMap`], so that we need to
229 /// [`clone`](core::clone::Clone::clone) hash_builder for passing it inside
230 /// two inner `HashMaps`.
231 ///
232 /// # Examples
233 ///
234 /// ```
235 /// use double_map::DHashMap;
236 /// use std::collections::hash_map::RandomState;
237 ///
238 /// let s = RandomState::new();
239 /// let mut map = DHashMap::with_capacity_and_hasher(5, s);
240 ///
241 /// // The created DHashMap holds none elements
242 /// assert_eq!(map.len(), 0);
243 /// // But it can hold at least 5 elements without reallocating
244 /// let empty_map_capacity = map.capacity();
245 /// assert!(empty_map_capacity >= 5);
246 ///
247 /// // Now we insert some 5 elements inside the created DHashMap
248 /// map.insert("One", 1, "a");
249 /// map.insert("Two", 2, "b");
250 /// map.insert("Three", 3, "c");
251 /// map.insert("Four", 4, "d");
252 /// map.insert("Five", 5, "e");
253 ///
254 /// // We can see that the DHashMap holds 5 elements
255 /// assert_eq!(map.len(), 5);
256 /// // But its capacity isn't changed
257 /// assert_eq!(map.capacity(), empty_map_capacity)
258 /// ```
259 #[inline]
260 pub fn with_capacity_and_hasher(capacity: usize, hash_builder: S) -> DHashMap<K1, K2, V, S> {
261 DHashMap {
262 value_map: HashMap::with_capacity_and_hasher(capacity, hash_builder.clone()),
263 key_map: HashMap::with_capacity_and_hasher(capacity, hash_builder),
264 }
265 }
266}
267
268impl<K1, K2, V, S> DHashMap<K1, K2, V, S> {
269 /// Returns the number of elements the map can hold without reallocating.
270 ///
271 /// This number is a lower bound; the `DHashMap<K1, K2, V>` collection might
272 /// be able to hold more, but is guaranteed to be able to hold at least this many.
273 ///
274 /// # Note
275 ///
276 /// Internally [`DHashMap`] use two [`HashMap`](`std::collections::HashMap`). One of type
277 /// `HashMap<K1, (K2, V)>` to hold the `(K2, V)` tuple, and second one of type
278 /// `HashMap<K2, K1>` just for holding the primary key of type `K1`.
279 ///
280 /// The [`capacity`](`DHashMap::capacity`) method return the capacity of first
281 /// [`HashMap`](`std::collections::HashMap`) of type `HashMap<K1, (K2, V)>`.
282 /// So that, if you previously used [`insert_unchecked`](DHashMap::insert_unchecked) method,
283 /// the returned capacity may be not equal to actual capacity of second internal
284 /// `HashMap<K2, K1>` in case of **unsynchronization** between first keys of type `K1`
285 /// and second keys of type `K2`. See [`insert_unchecked`](DHashMap::insert_unchecked)
286 /// method documentation for more.
287 ///
288 /// # Examples
289 ///
290 /// ```
291 /// use double_map::DHashMap;
292 /// let map = DHashMap::<i32, &str, &str>::with_capacity(16);
293 ///
294 /// // The created DHashMap can hold at least 16 elements
295 /// assert!(map.capacity() >= 16);
296 /// // But for now it doesn't hold any elements
297 /// assert_eq!(map.len(), 0);
298 /// ```
299 #[inline]
300 pub fn capacity(&self) -> usize {
301 // we only take it into account because it contains the most important part of
302 // hashtable - the value
303 self.value_map.capacity()
304 }
305
306 /// An iterator visiting all keys in arbitrary order.
307 /// The iterator element is tuple of type `(&'a K1, &'a K2)`.
308 ///
309 /// # Note
310 ///
311 /// Internally [`DHashMap`] use two [`HashMap`](`std::collections::HashMap`). One of type
312 /// `HashMap<K1, (K2, V)>` to hold the `(K2, V)` tuple, and second one of type
313 /// `HashMap<K2, K1>` just for holding the primary key of type `K1`.
314 ///
315 /// Created iterator iterate only through first [`HashMap`](`std::collections::HashMap`)
316 /// of type `HashMap<K1, (K2, V)>`.
317 /// So that, if you previously used [`insert_unchecked`](DHashMap::insert_unchecked) method,
318 /// this method can return false second keys (key #2) in case of **unsynchronization**
319 /// between first keys of type `K1` and second keys of type `K2`. See
320 /// [`insert_unchecked`](DHashMap::insert_unchecked) method documentation for more.
321 ///
322 /// # Examples
323 ///
324 /// ```
325 /// use double_map::DHashMap;
326 ///
327 /// let mut map = DHashMap::new();
328 /// map.insert("a", 1, "One");
329 /// map.insert("b", 2, "Two");
330 /// map.insert("c", 3, "Three");
331 ///
332 /// assert_eq!(map.len(), 3);
333 ///
334 /// for (key1, key2) in map.keys() {
335 /// println!("key1: {}, key2: {}", key1, key2);
336 /// assert!(
337 /// (key1, key2) == (&"a", &1) ||
338 /// (key1, key2) == (&"b", &2) ||
339 /// (key1, key2) == (&"c", &3)
340 /// );
341 /// }
342 ///
343 /// assert_eq!(map.len(), 3);
344 /// ```
345 pub fn keys(&self) -> Keys<'_, K1, K2, V> {
346 Keys { inner: self.iter() }
347 }
348
349 /// Creates a consuming iterator visiting all the keys in arbitrary order.
350 /// The map cannot be used after calling this. The iterator element is tuple
351 /// of type `(K1, K2)`.
352 ///
353 /// # Note
354 ///
355 /// Created iterator contains only content of the first [`HashMap<K1, (K2, V)>`](`std::collections::HashMap`)
356 /// which is used underneath of the [`DHashMap`].
357 ///
358 /// So that, if you previously used [`insert_unchecked`](DHashMap::insert_unchecked) method,
359 /// this method can return false second keys (key #2) in case of **unsynchronization**
360 /// between first keys of type `K1` and second keys of type `K2`. See
361 /// [`insert_unchecked`](DHashMap::insert_unchecked) method documentation for more.
362 ///
363 /// # Examples
364 ///
365 /// ```
366 /// use double_map::{DHashMap, dhashmap};
367 ///
368 /// let map = dhashmap![
369 /// ("a", 1) => "One",
370 /// ("b", 2) => "Two",
371 /// ("c", 3) => "Three",
372 /// ];
373 ///
374 /// let mut vec: Vec<(&str, i32)> = map.into_keys().collect();
375 /// // The `IntoKeys` iterator produces keys in arbitrary order, so the
376 /// // keys must be sorted to test them against a sorted array.
377 /// vec.sort_unstable();
378 /// assert_eq!(vec, [("a", 1), ("b", 2), ("c", 3)]);
379 /// ```
380 #[inline]
381 pub fn into_keys(self) -> IntoKeys<K1, K2, V> {
382 IntoKeys {
383 inner: self.into_iter(),
384 }
385 }
386
387 /// An iterator visiting all values in arbitrary order.
388 /// The iterator element type is `&'a V`.
389 ///
390 /// # Examples
391 ///
392 /// ```
393 /// use double_map::DHashMap;
394 ///
395 /// let mut map = DHashMap::new();
396 /// map.insert("a", 1, "One");
397 /// map.insert("b", 2, "Two");
398 /// map.insert("c", 3, "Three");
399 ///
400 /// assert_eq!(map.len(), 3);
401 ///
402 /// for value in map.values() {
403 /// println!("value = {}", value);
404 /// assert!(value == &"One" || value == &"Two" || value == &"Three");
405 /// }
406 ///
407 /// assert_eq!(map.len(), 3);
408 /// ```
409 pub fn values(&self) -> Values<'_, K1, K2, V> {
410 Values { inner: self.iter() }
411 }
412
413 /// An iterator visiting all values mutably in arbitrary order.
414 /// The iterator element type is `&'a mut V`.
415 ///
416 /// # Examples
417 ///
418 /// ```
419 /// use double_map::DHashMap;
420 ///
421 /// let mut map = DHashMap::new();
422 ///
423 /// map.insert("a", "One", 1);
424 /// map.insert("b", "Two", 2);
425 /// map.insert("c", "Three", 3);
426 ///
427 /// assert_eq!(map.len(), 3);
428 ///
429 /// for value in map.values_mut() {
430 /// *value = *value + 10;
431 /// }
432 ///
433 /// for value in map.values() {
434 /// println!("value = {}", value);
435 /// assert!(value == &11 || value == &12 || value == &13);
436 /// }
437 ///
438 /// assert_eq!(map.len(), 3);
439 /// ```
440 pub fn values_mut(&mut self) -> ValuesMut<'_, K1, K2, V> {
441 ValuesMut {
442 inner: self.iter_mut(),
443 }
444 }
445
446 /// Creates a consuming iterator visiting all the values in arbitrary order.
447 /// The map cannot be used after calling this. The iterator element type is `V`.
448 ///
449 /// # Examples
450 ///
451 /// ```
452 /// use double_map::{DHashMap, dhashmap};
453 ///
454 /// let map = dhashmap![
455 /// ("a", 1) => 10,
456 /// ("b", 2) => 20,
457 /// ("c", 3) => 30,
458 /// ];
459 ///
460 /// let mut vec: Vec<i32> = map.into_values().collect();
461 /// // The `IntoValues` iterator produces values in arbitrary order, so
462 /// // the values must be sorted to test them against a sorted array.
463 /// vec.sort_unstable();
464 /// assert_eq!(vec, [10, 20, 30]);
465 /// ```
466 #[inline]
467 pub fn into_values(self) -> IntoValues<K1, K2, V> {
468 IntoValues {
469 inner: self.into_iter(),
470 }
471 }
472
473 /// An iterator visiting all keys-value tuples in arbitrary order.
474 /// The iterator element is tuple of type `(&'a K1, &'a K2, &'a V)`.
475 ///
476 /// # Note
477 ///
478 /// Internally [`DHashMap`] use two [`HashMap`](`std::collections::HashMap`). One of type
479 /// `HashMap<K1, (K2, V)>` to hold the `(K2, V)` tuple, and second one of type
480 /// `HashMap<K2, K1>` just for holding the primary key of type `K1`.
481 ///
482 /// Created iterator iterate only through first [`HashMap`](`std::collections::HashMap`)
483 /// of type `HashMap<K1, (K2, V)>`.
484 /// So that, if you previously used [`insert_unchecked`](DHashMap::insert_unchecked) method,
485 /// this method can return false second keys (key #2) in case of **unsynchronization**
486 /// between first keys of type `K1` and second keys of type `K2`. See
487 /// [`insert_unchecked`](DHashMap::insert_unchecked) method documentation for more.
488 ///
489 /// # Examples
490 ///
491 /// ```
492 /// use double_map::DHashMap;
493 ///
494 /// let mut map = DHashMap::new();
495 /// map.insert("a", 1, "One");
496 /// map.insert("b", 2, "Two");
497 /// map.insert("c", 3, "Three");
498 ///
499 /// assert_eq!(map.len(), 3);
500 ///
501 /// for (key1, key2, value) in map.iter() {
502 /// println!("key1: {}, key2: {}, value: {}", key1, key2, value);
503 /// assert!(
504 /// (key1, key2, value) == (&"a", &1, &"One") ||
505 /// (key1, key2, value) == (&"b", &2, &"Two") ||
506 /// (key1, key2, value) == (&"c", &3, &"Three")
507 /// );
508 /// }
509 ///
510 /// assert_eq!(map.len(), 3);
511 /// ```
512 pub fn iter(&self) -> Iter<'_, K1, K2, V> {
513 Iter {
514 base: self.value_map.iter(),
515 }
516 }
517
518 /// An iterator visiting all keys-value tuples in arbitrary order,
519 /// with mutable references to the values.
520 /// The iterator element is tuple of type`(&'a K1, &'a K2, &'a mut V)`.
521 ///
522 /// # Note
523 ///
524 /// Internally [`DHashMap`] use two [`HashMap`](`std::collections::HashMap`). One of type
525 /// `HashMap<K1, (K2, V)>` to hold the `(K2, V)` tuple, and second one of type
526 /// `HashMap<K2, K1>` just for holding the primary key of type `K1`.
527 ///
528 /// Created iterator iterate only through first [`HashMap`](`std::collections::HashMap`)
529 /// of type `HashMap<K1, (K2, V)>`.
530 /// So that, if you previously used [`insert_unchecked`](DHashMap::insert_unchecked) method,
531 /// this method can return false second keys (key #2) in case of **unsynchronization**
532 /// between first keys of type `K1` and second keys of type `K2`. See
533 /// [`insert_unchecked`](DHashMap::insert_unchecked) method documentation for more.
534 ///
535 /// # Examples
536 ///
537 /// ```
538 /// use double_map::DHashMap;
539 ///
540 /// let mut map = DHashMap::new();
541 /// map.insert("a", "One", 1);
542 /// map.insert("b", "Two", 2);
543 /// map.insert("c", "Three", 3);
544 ///
545 /// assert_eq!(map.len(), 3);
546 ///
547 /// // Update all values
548 /// for (_, _, value) in map.iter_mut() {
549 /// *value *= 2;
550 /// }
551 ///
552 /// for (key1, key2, value) in map.iter() {
553 /// println!("key1: {}, key2: {}, value: {}", key1, key2, value);
554 /// assert!(
555 /// (key1, key2, value) == (&"a", &"One", &2) ||
556 /// (key1, key2, value) == (&"b", &"Two", &4) ||
557 /// (key1, key2, value) == (&"c", &"Three", &6)
558 /// );
559 /// }
560 ///
561 /// assert_eq!(map.len(), 3);
562 /// ```
563 pub fn iter_mut(&mut self) -> IterMut<'_, K1, K2, V> {
564 IterMut {
565 base: self.value_map.iter_mut(),
566 }
567 }
568
569 /// Returns the number of elements in the map.
570 ///
571 /// # Note
572 ///
573 /// Internally [`DHashMap`] use two [`HashMap`](`std::collections::HashMap`). One of type
574 /// `HashMap<K1, (K2, V)>` to hold the `(K2, V)` tuple, and second one of type
575 /// `HashMap<K2, K1>` just for holding the primary key of type `K1`.
576 ///
577 /// The [`len`](`DHashMap::len`) method return the number of elements contained inside first
578 /// [`HashMap`](`std::collections::HashMap`) of type `HashMap<K1, (K2, V)>`.
579 /// So that, if you previously used [`insert_unchecked`](DHashMap::insert_unchecked) method,
580 /// the returned length may be not equal to actual number of elements inside of second internal
581 /// `HashMap<K2, K1>` in case of **unsynchronization** between first keys of type `K1`
582 /// and second keys of type `K2`. See [`insert_unchecked`](DHashMap::insert_unchecked)
583 /// method documentation for more.
584 ///
585 /// # Examples
586 ///
587 /// ```
588 /// use double_map::{DHashMap, dhashmap};
589 ///
590 /// let mut a = DHashMap::new();
591 /// // The created DHashMap doesn't hold any elements
592 /// assert_eq!(a.len(), 0);
593 /// // We insert one element
594 /// a.insert(1, "Breakfast", "Pancakes");
595 /// // And can be sure that DHashMap holds one element
596 /// assert_eq!(a.len(), 1);
597 ///
598 /// let map = dhashmap![
599 /// 1, "Breakfast" => "Pancakes",
600 /// 2, "Lunch" => "Sandwich",
601 /// ];
602 /// assert_eq!(map.len(), 2);
603 /// ```
604 #[inline]
605 pub fn len(&self) -> usize {
606 // we only take it into account because it contains the most important part of
607 // hashtable - the value
608 self.value_map.len()
609 }
610
611 /// Returns `true` if the map contains no elements.
612 ///
613 /// # Note
614 ///
615 /// Internally [`DHashMap`] use two [`HashMap`](`std::collections::HashMap`). One of type
616 /// `HashMap<K1, (K2, V)>` to hold the `(K2, V)` tuple, and second one of type
617 /// `HashMap<K2, K1>` just for holding the primary key of type `K1`.
618 ///
619 /// The [`is_empty`](`DHashMap::is_empty`) method return the status of first
620 /// [`HashMap`](`std::collections::HashMap`) of type `HashMap<K1, (K2, V)>`.
621 ///
622 /// # Examples
623 ///
624 /// ```
625 /// use double_map::DHashMap;
626 ///
627 /// let mut a = DHashMap::new();
628 /// // The created DHashMap doesn't hold any elements, so it's empty
629 /// assert!(a.is_empty() && a.len() == 0);
630 /// // We insert one element
631 /// a.insert(1, "a", "One");
632 /// // And can be sure that DHashMap is not empty but holds one element
633 /// assert!(!a.is_empty() && a.len() == 1);
634 /// ```
635 #[inline]
636 pub fn is_empty(&self) -> bool {
637 // we only take it into account because it contains the most important part of
638 // hashtable - the value
639 self.value_map.is_empty()
640 }
641
642 /// Clears the map, returning all keys-value tuples as an arbitrary
643 /// order iterator. The iterator element is tuple of type `(K1, K2, V)`.
644 /// Keeps the allocated memory for reuse.
645 ///
646 /// # Note
647 ///
648 /// Internally [`DHashMap`] use two [`HashMap`](`std::collections::HashMap`). One of type
649 /// `HashMap<K1, (K2, V)>` to hold the `(K2, V)` tuple, and second one of type
650 /// `HashMap<K2, K1>` just for holding the primary key of type `K1`.
651 ///
652 /// Created iterator contain elements only the first [`HashMap`](`std::collections::HashMap`)
653 /// of type `HashMap<K1, (K2, V)>`.
654 /// So that, if you previously used [`insert_unchecked`](DHashMap::insert_unchecked) method,
655 /// this method can return false second keys (key #2) in case of **unsynchronization**
656 /// between first keys of type `K1` and second keys of type `K2`. See
657 /// [`insert_unchecked`](DHashMap::insert_unchecked) method documentation for more.
658 ///
659 /// # Examples
660 ///
661 /// ```
662 /// use double_map::DHashMap;
663 ///
664 /// // We insert three elements
665 /// let mut a = DHashMap::new();
666 /// a.insert("apple", 1, "a");
667 /// a.insert("banana", 2, "b");
668 /// a.insert("Cherry", 3, "c");
669 ///
670 /// // We can see that DHashMap hold three elements
671 /// assert_eq!(a.len(), 3);
672 ///
673 /// // Also we reserve memory for holding additionally at least 20 elements,
674 /// // so that DHashMap can now hold 23 elements or more
675 /// a.reserve(20);
676 /// let capacity_before_drain = a.capacity();
677 ///
678 /// for (key1, key2, value) in a.drain() {
679 /// println!{"key1: {}, key2: {}, value: {}", key1, key2, value}
680 /// assert!(
681 /// (key1, key2, value) == ("apple", 1, "a") ||
682 /// (key1, key2, value) == ("banana", 2, "b") ||
683 /// (key1, key2, value) == ("Cherry", 3, "c")
684 /// );
685 /// }
686 ///
687 /// // As we can see, the map is empty and contain no element
688 /// assert!(a.is_empty() && a.len() == 0);
689 /// // But map capacity is equal to old one and can hold at least 23 elements
690 /// assert!(a.capacity() == capacity_before_drain && a.capacity() >= 23);
691 /// ```
692 #[inline]
693 pub fn drain(&mut self) -> Drain<'_, K1, K2, V> {
694 self.key_map.drain();
695 Drain {
696 base: self.value_map.drain(),
697 }
698 }
699
700 /// Clears the map, removing all keys-value tuples.
701 /// Keeps the allocated memory for reuse.
702 ///
703 /// # Examples
704 ///
705 /// ```
706 /// use double_map::{DHashMap, dhashmap};
707 ///
708 /// let mut a = dhashmap![
709 /// 1, "Breakfast" => "Pancakes",
710 /// 2, "Lunch" => "Sandwich",
711 /// ];
712 ///
713 /// // We can that see DHashMap holds two elements
714 /// assert_eq!(a.len(), 2);
715 /// let capacity_before_clearing = a.capacity();
716 ///
717 /// a.clear();
718 ///
719 /// // And now the map is empty and contains no elements
720 /// assert!(a.is_empty() && a.len() == 0);
721 /// // But map capacity is equal to the old one
722 /// assert_eq!(a.capacity(), capacity_before_clearing);
723 /// ```
724 #[inline]
725 pub fn clear(&mut self) {
726 self.value_map.clear();
727 self.key_map.clear();
728 }
729
730 /// Returns a reference to the map's [`BuildHasher`].
731 ///
732 /// # Examples
733 ///
734 /// ```
735 /// use double_map::DHashMap;
736 /// use std::collections::hash_map::RandomState;
737 ///
738 /// let hasher = RandomState::new();
739 /// let map: DHashMap<i32, i32, i32> = DHashMap::with_hasher(hasher);
740 /// let hasher: &RandomState = map.hasher();
741 /// ```
742 #[inline]
743 pub fn hasher(&self) -> &S {
744 self.value_map.hasher()
745 }
746}
747
748impl<K1, K2, V, S> DHashMap<K1, K2, V, S>
749where
750 K1: Eq + Hash,
751 K2: Eq + Hash,
752 S: BuildHasher,
753{
754 /// Reserves capacity for at least `additional` more elements to be inserted
755 /// in the `DHashMap<K1, K2, V>`. The collection may reserve more space to avoid
756 /// frequent reallocations.
757 ///
758 /// # Panics
759 ///
760 /// Panics if the new allocation size overflows `usize::Max / 2`.
761 ///
762 /// # Examples
763 ///
764 /// ```
765 /// use double_map::DHashMap;
766 /// let mut a = DHashMap::<&str, i128, &str>::new();
767 /// a.insert("apple", 1, "a");
768 /// a.insert("banana", 2, "b");
769 /// a.insert("cherry", 3, "c");
770 ///
771 /// // We reserve space for additional 10 elements
772 /// a.reserve(10);
773 /// // And can see that created DHashMap can hold at least 13 elements
774 /// assert!(a.capacity() >= 13);
775 /// ```
776 #[inline]
777 pub fn reserve(&mut self, additional: usize) {
778 self.value_map.reserve(additional);
779 self.key_map.reserve(additional);
780 }
781
782 /// Tries to reserve capacity for at least `additional` more elements to be inserted
783 /// in the given `DHashMap<K1, K2, V>`. The collection may reserve more space to avoid
784 /// frequent reallocations.
785 ///
786 /// # Errors
787 ///
788 /// If the capacity overflows, or the allocator reports a failure, then an error
789 /// is returned.
790 ///
791 /// # Examples
792 ///
793 /// ```
794 /// use std::collections::TryReserveError;
795 /// use double_map::DHashMap;
796 ///
797 /// let mut map: DHashMap<i32, &str, isize> = DHashMap::new();
798 /// map.try_reserve(20).expect("something go wrong");
799 ///
800 /// // So everything is Ok
801 /// let capacity = map.capacity();
802 /// assert!(capacity >= 20);
803 ///
804 /// // Let's check that it returns error if it can not reserve asked capacity
805 /// let result = map.try_reserve(usize::MAX);
806 /// match result {
807 /// Err(_) => println!("It is ok, error was expected"),
808 /// Ok(_) => unreachable!(),
809 /// }
810 /// // And capacity of the map isn't changed
811 /// assert_eq!(map.capacity(), capacity);
812 /// ```
813 #[inline]
814 pub fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError> {
815 self.value_map.try_reserve(additional)?;
816 self.key_map.try_reserve(additional)
817 }
818
819 /// Shrinks the capacity of the map as much as possible. It will drop
820 /// down as much as possible while maintaining the internal rules
821 /// and possibly leaving some space in accordance with the resize policy.
822 ///
823 /// Note that in general case the capacity is not *guaranteed* to shrink,
824 /// but a zero-length DHashMap should generally shrink to capacity zero.
825 ///
826 /// # Examples
827 ///
828 /// ```
829 /// use double_map::DHashMap;
830 /// let mut a = DHashMap::<i32, &str, &str>::with_capacity(16);
831 ///
832 /// // This DHashMap can hold at least 16 elements
833 /// let capacity_before_shrink = a.capacity();
834 /// assert!(capacity_before_shrink >= 16);
835 ///
836 /// // And after shrinking, map capacity is less than before
837 /// a.shrink_to_fit();
838 /// assert!(a.capacity() < capacity_before_shrink);
839 ///
840 /// // If we reserve some memory and insert some elements
841 /// a.reserve(10);
842 /// a.insert(1, "a", "One");
843 /// a.insert(2, "b", "Two");
844 /// assert!(a.capacity() >= 10);
845 ///
846 /// // After applying shrink_to_fit method, the capacity less than
847 /// // reserved before, but inserted elements are still inside map
848 /// a.shrink_to_fit();
849 /// assert!(a.capacity() >= 2 && a.capacity() < 10);
850 /// assert_eq!(a.get_key1(&1), Some(&"One"));
851 /// assert_eq!(a.get_key1(&2), Some(&"Two"))
852 /// ```
853 #[inline]
854 pub fn shrink_to_fit(&mut self) {
855 self.value_map.shrink_to_fit();
856 self.key_map.shrink_to_fit();
857 }
858
859 /// Shrinks the capacity of the map with a lower limit. It will drop
860 /// down no lower than the supplied limit while maintaining the internal rules
861 /// and possibly leaving some space in accordance with the resize policy.
862 ///
863 /// If the current capacity is less than the lower limit, this is a no-op.
864 ///
865 /// # Examples
866 ///
867 /// ```
868 /// use double_map::DHashMap;
869 ///
870 /// let mut map: DHashMap<i32, i32, i32> = DHashMap::with_capacity(100);
871 /// map.insert(1, 2, 3);
872 /// map.insert(4, 5, 6);
873 /// map.insert(7, 8, 9);
874 /// assert!(map.capacity() >= 100);
875 ///
876 /// // We have only 3 elements inside map, so it works
877 /// map.shrink_to(10);
878 /// assert!(map.capacity() >= 10 && map.capacity() < 100);
879 ///
880 /// // If we try shrink_to the capacity, that less than elements quantity inside map
881 /// map.shrink_to(0);
882 /// // So it works partially, but the resulting capacity is not less than quantity
883 /// // of elements inside the map
884 /// assert!(map.capacity() >= 3 && map.capacity() < 10);
885 /// ```
886 #[inline]
887 pub fn shrink_to(&mut self, min_capacity: usize) {
888 self.value_map.shrink_to(min_capacity);
889 self.key_map.shrink_to(min_capacity);
890 }
891
892 /// Returns a reference to the value corresponding to the given primary key `(key #1)`.
893 ///
894 /// The key may be any borrowed form of the map's key type, but
895 /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
896 /// the key type.
897 ///
898 /// # Examples
899 ///
900 /// ```
901 /// use double_map::DHashMap;
902 ///
903 /// let mut map = DHashMap::new();
904 /// map.insert(1, "a", "One");
905 /// assert_eq!(map.get_key1(&1), Some(&"One"));
906 /// assert_eq!(map.get_key1(&2), None);
907 /// ```
908 #[inline]
909 pub fn get_key1<Q: ?Sized>(&self, k1: &Q) -> Option<&V>
910 where
911 K1: Borrow<Q>,
912 Q: Hash + Eq,
913 {
914 match self.value_map.get(k1) {
915 Some((_, value)) => Some(value),
916 None => None,
917 }
918 }
919
920 /// Returns a reference to the value corresponding to the given secondary key `(key #2)`.
921 ///
922 /// The key may be any borrowed form of the map's key type, but
923 /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
924 /// the key type.
925 ///
926 /// # Examples
927 ///
928 /// ```
929 /// use double_map::DHashMap;
930 ///
931 /// let mut map = DHashMap::new();
932 /// map.insert(1, "a", "One");
933 /// assert_eq!(map.get_key2(&"a"), Some(&"One"));
934 /// assert_eq!(map.get_key2(&"b"), None);
935 /// ```
936 #[inline]
937 pub fn get_key2<Q: ?Sized>(&self, k2: &Q) -> Option<&V>
938 where
939 K2: Borrow<Q>,
940 Q: Hash + Eq,
941 {
942 match self.key_map.get(k2) {
943 Some(k1) => match self.value_map.get(k1) {
944 Some((_, value)) => Some(value),
945 None => None,
946 },
947 None => None,
948 }
949 }
950
951 /// Returns a reference to the value corresponding to the given primary key `(key #1)`
952 /// and secondary key `(key #2)` if they both exist and refer to the same value.
953 ///
954 /// The keys may be any borrowed form of the map's keys type, but
955 /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
956 /// the keys type.
957 ///
958 /// # Note
959 /// Note that this [`get_keys`](DHashMap::get_keys) method return a reference to the value
960 /// only if two keys exist and refer to the same `value`.
961 ///
962 /// # Examples
963 ///
964 /// ```
965 /// use double_map::{DHashMap, dhashmap};
966 ///
967 /// let map = dhashmap! {
968 /// 1, "One" => String::from("Eins"),
969 /// 2, "Two" => String::from("Zwei"),
970 /// 3, "Three" => String::from("Drei"),
971 /// };
972 ///
973 /// // two keys exist and refer to the same value ("Eins")
974 /// assert_eq!(map.get_keys(&1, &"One" ), Some(&"Eins".to_owned()));
975 ///
976 /// // Both keys don't exist
977 /// assert_eq!(map.get_keys(&4, &"Four"), None);
978 ///
979 /// // Both keys exist but refer to the different value (key1: 1 refers to "Eins",
980 /// // key2: "Two" refers to "Zwei")
981 /// assert_eq!(map.get_keys(&1, &"Two" ), None);
982 /// assert_eq!(map.get_key1(&1).unwrap(), "Eins");
983 /// assert_eq!(map.get_key2(&"Two").unwrap(), "Zwei");
984 /// ```
985 #[inline]
986 pub fn get_keys<Q1: ?Sized, Q2: ?Sized>(&self, k1: &Q1, k2: &Q2) -> Option<&V>
987 where
988 K1: Borrow<Q1>,
989 K2: Borrow<Q2>,
990 Q1: Hash + Eq,
991 Q2: Hash + Eq,
992 {
993 match self.value_map.get_key_value(k1) {
994 Some((k1_v, (k2_v, val))) => match self.key_map.get_key_value(k2) {
995 Some((k2_k, k1_k)) if k1_v == k1_k && k2_v == k2_k => Some(val),
996 _ => None,
997 },
998 None => None,
999 }
1000 }
1001
1002 /// Returns the key-value pair corresponding to the supplied primary key `(key #1)`.
1003 /// Return the tuple of type `(&'a K1, &'a V)`.
1004 ///
1005 /// The supplied key may be any borrowed form of the map's key type, but
1006 /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
1007 /// the key type.
1008 ///
1009 /// # Examples
1010 ///
1011 /// ```
1012 /// use double_map::DHashMap;
1013 ///
1014 /// let mut map = DHashMap::new();
1015 /// map.insert(1, 10, "a");
1016 /// assert_eq!(map.get_key1_value(&1), Some((&1, &"a")));
1017 /// assert_eq!(map.get_key1_value(&2), None);
1018 /// ```
1019 #[inline]
1020 pub fn get_key1_value<Q: ?Sized>(&self, k1: &Q) -> Option<(&K1, &V)>
1021 where
1022 K1: Borrow<Q>,
1023 Q: Hash + Eq,
1024 {
1025 match self.value_map.get_key_value(k1) {
1026 Some((key_one, (_, value))) => Some((key_one, value)),
1027 None => None,
1028 }
1029 }
1030
1031 /// Returns the key-value pair corresponding to the supplied secondary key `(key #2)`.
1032 /// Return the tuple of type `(&'a K2, &'a V)`.
1033 ///
1034 /// The supplied key may be any borrowed form of the map's key type, but
1035 /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
1036 /// the key type.
1037 ///
1038 /// # Examples
1039 ///
1040 /// ```
1041 /// use double_map::DHashMap;
1042 ///
1043 /// let mut map = DHashMap::new();
1044 /// map.insert(1, 10, "a");
1045 /// assert_eq!(map.get_key2_value(&10), Some((&10, &"a")));
1046 /// assert_eq!(map.get_key2_value(&20), None);
1047 /// ```
1048 #[inline]
1049 pub fn get_key2_value<Q: ?Sized>(&self, k2: &Q) -> Option<(&K2, &V)>
1050 where
1051 K2: Borrow<Q>,
1052 Q: Hash + Eq,
1053 {
1054 match self.key_map.get_key_value(k2) {
1055 Some((key_two, key_one)) => match self.value_map.get(key_one) {
1056 Some((_, value)) => Some((key_two, value)),
1057 None => None,
1058 },
1059 None => None,
1060 }
1061 }
1062
1063 /// Returns a reference to the keys-value tuple corresponding to the given primary
1064 /// ans secondary keys if they both exist and refer to the same value.
1065 /// Return tuple of type `(&'a K1, &'a K2, &'a V)`.
1066 ///
1067 /// The supplied keys may be any borrowed form of the map's keys type, but
1068 /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
1069 /// the keys type.
1070 ///
1071 /// # Note
1072 ///
1073 /// Note that this [`get_keys_value`](DHashMap::get_keys_value) method return the
1074 /// tuple of type`(&'a K1, &'a K2, &'a V)` only if two keys exist and refer to
1075 /// the same `value`.
1076 ///
1077 /// # Example
1078 ///
1079 /// ```
1080 /// use double_map::{DHashMap, dhashmap};
1081 ///
1082 /// let map = dhashmap! {
1083 /// 1, "One" => "Eins",
1084 /// 2, "Two" => "Zwei",
1085 /// 3, "Three" => "Drei",
1086 /// };
1087 ///
1088 /// // two key exist and refer to the same value ("Eins")
1089 /// assert_eq!(map.get_keys_value(&1, &"One").unwrap(), (&1, &"One", &"Eins"));
1090 ///
1091 /// // Both keys don't exist
1092 /// assert_eq!(map.get_keys_value(&4, &"Four"), None);
1093 ///
1094 /// // Both keys exist but refer to the different value
1095 /// // (key1: 1 refer to "Eins", key2: "Two" refer to "Zwei")
1096 /// assert_eq!(map.get_keys_value(&1, &"Two" ), None);
1097 /// assert_eq!(map.get_key1(&1).unwrap(), &"Eins");
1098 /// assert_eq!(map.get_key2(&"Two").unwrap(), &"Zwei");
1099 /// ```
1100 #[inline]
1101 pub fn get_keys_value<Q1: ?Sized, Q2: ?Sized>(&self, k1: &Q1, k2: &Q2) -> Option<(&K1, &K2, &V)>
1102 where
1103 K1: Borrow<Q1>,
1104 K2: Borrow<Q2>,
1105 Q1: Hash + Eq,
1106 Q2: Hash + Eq,
1107 {
1108 match self.value_map.get_key_value(k1) {
1109 Some((k1_v, (k2_v, val))) => match self.key_map.get_key_value(k2) {
1110 Some((k2_k, k1_k)) if k1_v == k1_k && k2_v == k2_k => Some((k1_v, k2_k, val)),
1111 _ => None,
1112 },
1113 None => None,
1114 }
1115 }
1116
1117 /// Returns `true` if the map contains a value for the specified primary key `(key #1)`.
1118 ///
1119 /// The key may be any borrowed form of the map's key type, but
1120 /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
1121 /// the key type
1122 ///
1123 /// # Example
1124 ///
1125 /// ```
1126 /// use double_map::{DHashMap, dhashmap};
1127 ///
1128 /// let map = dhashmap! {
1129 /// 1, "One" => String::from("Eins"),
1130 /// 2, "Two" => String::from("Zwei"),
1131 /// 3, "Three" => String::from("Drei"),
1132 /// };
1133 ///
1134 /// assert!( map.contains_key1(&1));
1135 /// assert!(!map.contains_key1(&4));
1136 /// ```
1137 #[inline]
1138 pub fn contains_key1<Q: ?Sized>(&self, k1: &Q) -> bool
1139 where
1140 K1: Borrow<Q>,
1141 Q: Hash + Eq,
1142 {
1143 self.value_map.contains_key(k1)
1144 }
1145
1146 /// Returns `true` if the map contains a value for the specified secondary key `(key #2)`.
1147 ///
1148 /// The key may be any borrowed form of the map's key type, but
1149 /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
1150 /// the key type
1151 ///
1152 /// # Example
1153 ///
1154 /// ```
1155 /// use double_map::{DHashMap, dhashmap};
1156 ///
1157 /// let map = dhashmap! {
1158 /// 1, "One" => String::from("Eins"),
1159 /// 2, "Two" => String::from("Zwei"),
1160 /// 3, "Three" => String::from("Drei"),
1161 /// };
1162 ///
1163 /// assert!( map.contains_key2(&"One") );
1164 /// assert!(!map.contains_key2(&"Four"));
1165 /// ```
1166 #[inline]
1167 pub fn contains_key2<Q: ?Sized>(&self, k2: &Q) -> bool
1168 where
1169 K2: Borrow<Q>,
1170 Q: Hash + Eq,
1171 {
1172 self.key_map.contains_key(k2)
1173 }
1174
1175 /// Returns `true` if the map contains a value for the specified primary key `(key #1)`
1176 /// and secondary key `(key #2)` and they both refer to the same value.
1177 ///
1178 /// The keys may be any borrowed form of the map's keys type, but
1179 /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
1180 /// the keys type.
1181 ///
1182 /// # Note
1183 /// Note that this [`contains_keys`](DHashMap::contains_keys) method return `true` only
1184 /// if two keys exist and refer to the same `value`.
1185 ///
1186 /// # Example
1187 ///
1188 /// ```
1189 /// use double_map::{DHashMap, dhashmap};
1190 ///
1191 /// let map = dhashmap! {
1192 /// 1, "One" => String::from("Eins"),
1193 /// 2, "Two" => String::from("Zwei"),
1194 /// 3, "Three" => String::from("Drei"),
1195 /// };
1196 ///
1197 /// // two keys exist and refer to the same value ("Eins")
1198 /// assert_eq!(map.contains_keys(&1, &"One" ), true );
1199 ///
1200 /// // Both keys don't exist
1201 /// assert_eq!(map.contains_keys(&4, &"Four"), false);
1202 ///
1203 /// // Both keys exist but refer to the different value (key1: 1 refers to "Eins",
1204 /// // key2: "Two" refers to "Zwei")
1205 /// assert_eq!(map.contains_keys(&1, &"Two" ), false);
1206 /// assert!(map.contains_key1(&1) == true && map.get_key1(&1).unwrap() == "Eins");
1207 /// assert!(map.contains_key2(&"Two") == true && map.get_key2(&"Two").unwrap() == "Zwei");
1208 /// ```
1209 #[inline]
1210 pub fn contains_keys<Q1: ?Sized, Q2: ?Sized>(&self, k1: &Q1, k2: &Q2) -> bool
1211 where
1212 K1: Borrow<Q1>,
1213 K2: Borrow<Q2>,
1214 Q1: Hash + Eq,
1215 Q2: Hash + Eq,
1216 {
1217 match self.value_map.get_key_value(k1) {
1218 Some((k1_v, (k2_v, _))) => match self.key_map.get_key_value(k2) {
1219 Some((k2_k, k1_k)) => k1_v == k1_k && k2_v == k2_k,
1220 None => false,
1221 },
1222 None => false,
1223 }
1224 }
1225
1226 /// Returns a mutable reference to the value corresponding to
1227 /// the given primary key `(key #1)`.
1228 ///
1229 /// The key may be any borrowed form of the map's key type, but
1230 /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
1231 /// the key type.
1232 ///
1233 /// # Examples
1234 ///
1235 /// ```
1236 /// use double_map::DHashMap;
1237 ///
1238 /// let mut map = DHashMap::new();
1239 /// map.insert(1, "a", "One");
1240 /// if let Some(x) = map.get_mut_key1(&1) {
1241 /// *x = "First";
1242 /// }
1243 /// assert_eq!(map.get_key1(&1), Some(&"First"));
1244 /// ```
1245 #[inline]
1246 pub fn get_mut_key1<Q: ?Sized>(&mut self, k1: &Q) -> Option<&mut V>
1247 where
1248 K1: Borrow<Q>,
1249 Q: Hash + Eq,
1250 {
1251 match self.value_map.get_mut(k1) {
1252 Some((_, value)) => Some(value),
1253 None => None,
1254 }
1255 }
1256
1257 /// Returns a mutable reference to the value corresponding to
1258 /// the given secondary key `(key #2)`.
1259 ///
1260 /// The key may be any borrowed form of the map's key type, but
1261 /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
1262 /// the key type.
1263 ///
1264 /// # Examples
1265 ///
1266 /// ```
1267 /// use double_map::DHashMap;
1268 ///
1269 /// let mut map = DHashMap::new();
1270 /// map.insert(1, "a", "One");
1271 /// if let Some(x) = map.get_mut_key2(&"a") {
1272 /// *x = "First";
1273 /// }
1274 /// assert_eq!(map.get_key2(&"a"), Some(&"First"));
1275 /// ```
1276 #[inline]
1277 pub fn get_mut_key2<Q: ?Sized>(&mut self, k2: &Q) -> Option<&mut V>
1278 where
1279 K2: Borrow<Q>,
1280 Q: Hash + Eq,
1281 {
1282 match self.key_map.get(k2) {
1283 Some(key) => match self.value_map.get_mut(key) {
1284 Some((_, value)) => Some(value),
1285 None => None,
1286 },
1287 None => None,
1288 }
1289 }
1290
1291 /// Returns a mutable reference to the value corresponding to the given primary key `(key #1)`
1292 /// and secondary key `(key #2)` if they both exist and refer to the same value.
1293 ///
1294 /// The keys may be any borrowed form of the map's keys type, but
1295 /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
1296 /// the keys type.
1297 ///
1298 /// # Note
1299 /// Note that this [`get_mut_keys`](DHashMap::get_mut_keys) method return a reference
1300 /// to the value only if two keys exist and refer to the same `value`.
1301 ///
1302 /// # Examples
1303 ///
1304 /// ```
1305 /// use double_map::{DHashMap, dhashmap};
1306 ///
1307 /// let mut map = dhashmap! {
1308 /// 1, "One" => String::from("One"),
1309 /// 2, "Two" => String::from("Two"),
1310 /// 3, "Three" => String::from("Three"),
1311 /// };
1312 ///
1313 /// // two keys exist and refer to the same value, so we have
1314 /// // a mutable reference to the value
1315 /// for (key_one, key_two) in (1..=3).zip(["One", "Two", "Three"]) {
1316 /// if let Some(value) = map.get_mut_keys(&key_one, &key_two) {
1317 /// value.push_str(" mississippi");
1318 /// }
1319 /// }
1320 ///
1321 /// // We can see that all values updated
1322 /// assert_eq!(map.get_key1(&1), Some(&"One mississippi".to_owned()));
1323 /// assert_eq!(map.get_key1(&2), Some(&"Two mississippi".to_owned()));
1324 /// assert_eq!(map.get_key1(&3), Some(&"Three mississippi".to_owned()));
1325 ///
1326 /// // But if both keys don't exist we don't have a mutable reference to the value
1327 /// assert_eq!(map.get_mut_keys(&4, &"Four"), None);
1328 ///
1329 /// // If both keys exist but refer to the different value we also don't have
1330 /// // a mutable reference to the value
1331 /// assert_eq!(map.get_mut_keys(&1, &"Two" ), None);
1332 /// assert_eq!(map.get_key1(&1).unwrap(), "One mississippi");
1333 /// assert_eq!(map.get_key2(&"Two").unwrap(), "Two mississippi");
1334 /// ```
1335 #[inline]
1336 pub fn get_mut_keys<Q1: ?Sized, Q2: ?Sized>(&mut self, k1: &Q1, k2: &Q2) -> Option<&mut V>
1337 where
1338 K1: Borrow<Q1>,
1339 K2: Borrow<Q2>,
1340 Q1: Hash + Eq,
1341 Q2: Hash + Eq,
1342 {
1343 match self.value_map.get_mut(k1) {
1344 Some((ref k2_v, val)) => match self.key_map.get_key_value(k2) {
1345 Some((k2_k, k1_k)) if k2_v == k2_k && k1 == k1_k.borrow() => Some(val),
1346 _ => None,
1347 },
1348 None => None,
1349 }
1350 }
1351
1352 /// Removes element from the map using a primary key `(key #1)`,
1353 /// returning the value corresponding to the key if the key was
1354 /// previously in the map. Keeps the allocated memory for reuse.
1355 ///
1356 /// The key may be any borrowed form of the map's key type, but
1357 /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
1358 /// the key type.
1359 ///
1360 /// # Note
1361 ///
1362 /// This method removes not only value, but whole element including
1363 /// primary `K1` and secondary `K2` keys.
1364 ///
1365 /// # Examples
1366 ///
1367 /// ```
1368 /// use double_map::{DHashMap, dhashmap};
1369 ///
1370 /// // We create map with three elements
1371 /// let mut map = dhashmap! {
1372 /// 1, "One" => String::from("Eins"),
1373 /// 2, "Two" => String::from("Zwei"),
1374 /// 3, "Three" => String::from("Drei"),
1375 /// };
1376 ///
1377 /// // We can see that DHashMap holds three elements
1378 /// assert!(map.len() == 3 && map.capacity() >= 3);
1379 ///
1380 /// // Also we reserve memory for holding additionally at least 20 elements,
1381 /// // so that DHashMap can hold 23 elements or more
1382 /// map.reserve(20);
1383 /// let capacity_before_remove = map.capacity();
1384 ///
1385 /// // We remove element with key #1 from the map and get corresponding value
1386 /// assert_eq!(map.remove_key1(&1), Some("Eins".to_owned()));
1387 /// // If we try to remove the same element with key #1 twice we get None,
1388 /// // because that element was already removed
1389 /// assert_eq!(map.remove_key1(&1), None);
1390 ///
1391 /// // Now we remove all elements one by one, and can see that map holds nothing
1392 /// map.remove_key1(&2);
1393 /// map.remove_key1(&3);
1394 /// assert_eq!(map.len(), 0);
1395 ///
1396 /// // But map capacity is equal to the old one and can hold at least 23 elements
1397 /// assert!(map.capacity() == capacity_before_remove && map.capacity() >= 23);
1398 /// ```
1399 #[inline]
1400 pub fn remove_key1<Q: ?Sized>(&mut self, k1: &Q) -> Option<V>
1401 where
1402 K1: Borrow<Q>,
1403 Q: Hash + Eq,
1404 {
1405 match self.value_map.remove(k1) {
1406 Some((key, value)) => {
1407 self.key_map.remove(&key);
1408 Some(value)
1409 }
1410 None => None,
1411 }
1412 }
1413
1414 /// Removes element from the map using a secondary key `(key #2)`,
1415 /// returning the value corresponding to the key if the key was
1416 /// previously in the map. Keeps the allocated memory for reuse.
1417 ///
1418 /// The key may be any borrowed form of the map's key type, but
1419 /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
1420 /// the key type.
1421 ///
1422 /// # Note
1423 ///
1424 /// This method removes not only value, but whole element including
1425 /// primary `K1` and secondary `K2` keys.
1426 ///
1427 /// # Examples
1428 ///
1429 /// ```
1430 /// use double_map::{DHashMap, dhashmap};
1431 ///
1432 /// // We create map with three elements
1433 /// let mut map = dhashmap! {
1434 /// 1, "One" => String::from("Eins"),
1435 /// 2, "Two" => String::from("Zwei"),
1436 /// 3, "Three" => String::from("Drei"),
1437 /// };
1438 ///
1439 /// // We can see that DHashMap holds three elements
1440 /// assert!(map.len() == 3 && map.capacity() >= 3);
1441 ///
1442 /// // Also we reserve memory for holding additionally at least 20 elements,
1443 /// // so that DHashMap can hold 23 elements or more
1444 /// map.reserve(20);
1445 /// let capacity_before_remove = map.capacity();
1446 ///
1447 /// // We remove element with key #1 from the map and get corresponding value
1448 /// assert_eq!(map.remove_key2(&"One"), Some("Eins".to_owned()));
1449 /// // If we try to remove the same element with key #1 twice we get None,
1450 /// // because that element was already removed
1451 /// assert_eq!(map.remove_key2(&"One"), None);
1452 ///
1453 /// // Now we remove all elements one by one, and can see that map holds nothing
1454 /// map.remove_key2(&"Two");
1455 /// map.remove_key2(&"Three");
1456 /// assert_eq!(map.len(), 0);
1457 ///
1458 /// // But map capacity is equal to the old one and can hold at least 23 elements
1459 /// assert!(map.capacity() == capacity_before_remove && map.capacity() >= 23);
1460 /// ```
1461 #[inline]
1462 pub fn remove_key2<Q: ?Sized>(&mut self, k2: &Q) -> Option<V>
1463 where
1464 K2: Borrow<Q>,
1465 Q: Hash + Eq,
1466 {
1467 match self.key_map.remove(k2) {
1468 Some(key) => match self.value_map.remove(&key) {
1469 Some((_, value)) => Some(value),
1470 None => None,
1471 },
1472 None => None,
1473 }
1474 }
1475
1476 /// Removes element from the map corresponding to the given primary key `(key #1)`
1477 /// and secondary key `(key #2)` returning the value at the keys if the keys was
1478 /// previously in the map and refer to the same value. Keeps the allocated memory
1479 /// for reuse.
1480 ///
1481 /// The key may be any borrowed form of the map's key type, but
1482 /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
1483 /// the key type.
1484 ///
1485 /// # Examples
1486 ///
1487 /// ```
1488 /// use double_map::{DHashMap, dhashmap};
1489 ///
1490 /// // We create map with three elements
1491 /// let mut map = dhashmap! {
1492 /// 1, "One" => String::from("Eins"),
1493 /// 2, "Two" => String::from("Zwei"),
1494 /// 3, "Three" => String::from("Drei"),
1495 /// };
1496 ///
1497 /// // We can see that DHashMap holds three elements
1498 /// assert!(map.len() == 3 && map.capacity() >= 3);
1499 ///
1500 /// // Also we reserve memory for holding additionally at least 20 elements,
1501 /// // so that DHashMap can hold 23 elements or more
1502 /// map.reserve(20);
1503 /// let capacity_before_remove = map.capacity();
1504 ///
1505 /// // We remove element from the map and get corresponding value
1506 /// assert_eq!(map.remove_keys(&1, &"One"), Some("Eins".to_owned()));
1507 /// // If we try to remove the same element with these keys twice we get None,
1508 /// // because that element was already removed
1509 /// assert_eq!(map.remove_keys(&1, &"One"), None);
1510 ///
1511 /// // We get None if both keys don't exist in the map
1512 /// assert_eq!(map.remove_keys(&4, &"Four"), None);
1513 /// // Also we get None if both keys exist but refer to the different value
1514 /// assert_eq!(map.remove_keys(&2, &"Three"), None);
1515 /// assert_eq!(map.get_key1(&2).unwrap(), "Zwei");
1516 /// assert_eq!(map.get_key2(&"Three").unwrap(), "Drei");
1517 ///
1518 /// // Now we remove all elements one by one, and can see that map holds nothing
1519 /// map.remove_keys(&2, &"Two");
1520 /// map.remove_keys(&3, &"Three");
1521 /// assert_eq!(map.len(), 0);
1522 ///
1523 /// // But map capacity is equal to the old one and can hold at least 23 elements
1524 /// assert!(map.capacity() == capacity_before_remove && map.capacity() >= 23);
1525 /// ```
1526 #[inline]
1527 pub fn remove_keys<Q1: ?Sized, Q2: ?Sized>(&mut self, k1: &Q1, k2: &Q2) -> Option<V>
1528 where
1529 K1: Borrow<Q1>,
1530 K2: Borrow<Q2>,
1531 Q1: Hash + Eq,
1532 Q2: Hash + Eq,
1533 {
1534 match self.value_map.get_key_value(k1) {
1535 Some((k1_v, (k2_v, _))) => match self.key_map.get_key_value(k2) {
1536 Some((k2_k, k1_k)) if k1_v == k1_k && k2_v == k2_k => {
1537 self.key_map.remove(k2);
1538 match self.value_map.remove(k1) {
1539 Some((_, value)) => Some(value),
1540 None => None,
1541 }
1542 }
1543 _ => None,
1544 },
1545 None => None,
1546 }
1547 }
1548}
1549
1550impl<K1, K2, V, S> DHashMap<K1, K2, V, S>
1551where
1552 K1: Eq + Hash + Clone,
1553 K2: Eq + Hash + Clone,
1554 S: BuildHasher,
1555{
1556 /// Tries to get the given keys' corresponding entry in the map for in-place
1557 /// manipulation.
1558 ///
1559 /// Returns [`Entry`] enum if `all` of the following is `true`:
1560 /// - Both key #1 and key #2 are vacant.
1561 /// - If both key #1 and key #2 exist, they refer to the same value.
1562 ///
1563 /// When the above statements are `false`, [`entry`](DHashMap::entry) method returns
1564 /// [`EntryError`] structure which contains the [`ErrorKind`] enum, and the values
1565 /// of provided keys that were not used for creation entry (that can be used for
1566 /// another purpose).
1567 ///
1568 /// Depending on the points below, different [`ErrorKind`] variants may be returned:
1569 /// - When key #1 is vacant, but key #2 already exists with some value, the
1570 /// returned [`ErrorKind`] variant is [`ErrorKind::VacantK1AndOccupiedK2`].
1571 /// - When key #1 already exists with some value, but key #2 is vacant, the
1572 /// returned [`ErrorKind`] variant is [`ErrorKind::OccupiedK1AndVacantK2`].
1573 /// - When both key #1 and key #2 already exist with some values, but point
1574 /// to different entries (values) the returned [`ErrorKind`] variant is
1575 /// [`ErrorKind::KeysPointsToDiffEntries`].
1576 ///
1577 /// # Examples
1578 ///
1579 /// ```
1580 /// use double_map::DHashMap;
1581 /// use double_map::dhash_map::ErrorKind;
1582 ///
1583 /// let mut letters = DHashMap::new();
1584 ///
1585 /// for ch in "a short treatise on fungi".chars() {
1586 /// if let Ok(entry) = letters.entry(ch.clone(), ch) {
1587 /// let counter = entry.or_insert(0);
1588 /// *counter += 1;
1589 /// }
1590 /// }
1591 ///
1592 /// assert_eq!(letters.get_key1(&'s'), Some(&2));
1593 /// assert_eq!(letters.get_key1(&'t'), Some(&3));
1594 /// assert_eq!(letters.get_key1(&'u'), Some(&1));
1595 /// assert_eq!(letters.get_key1(&'y'), None);
1596 ///
1597 /// // Return `ErrorKind::OccupiedK1AndVacantK2` if key #1 already
1598 /// // exists with some value, but key #2 is vacant.
1599 /// let error_kind = letters.entry('s', 'y').unwrap_err().error;
1600 /// assert_eq!(error_kind, ErrorKind::OccupiedK1AndVacantK2);
1601 ///
1602 /// // Return `ErrorKind::VacantK1AndOccupiedK2` if key #1 is vacant,
1603 /// // but key #2 already exists with some value.
1604 /// let error_kind = letters.entry('y', 's').unwrap_err().error;
1605 /// assert_eq!(error_kind, ErrorKind::VacantK1AndOccupiedK2);
1606 ///
1607 /// // Return `ErrorKind::KeysPointsToDiffEntries` if both
1608 /// // key #1 and key #2 already exist with some values,
1609 /// // but point to different entries (values).
1610 /// let error_kind = letters.entry('s', 't').unwrap_err().error;
1611 /// assert_eq!(error_kind, ErrorKind::KeysPointsToDiffEntries);
1612 /// ```
1613 #[inline]
1614 pub fn entry(&mut self, k1: K1, k2: K2) -> Result<Entry<'_, K1, K2, V>, EntryError<K1, K2>> {
1615 // I don't like the way this function is done. But it looks like Hashmap::entry
1616 // (which internally uses hashbrown::rustc_entry::HashMap::rustc_entry) calls
1617 // self.reserve(1) when no key is found (vacant). It seems this one will lead
1618 // to constant allocation and deallocation, given that value_map.entry and
1619 // key_map.entry may not be vacant and occupied at the same time, so I'll
1620 // leave the implementation this way for now
1621 match self.value_map.get(&k1) {
1622 None => match self.key_map.get(&k2) {
1623 None => {
1624 // SAFETY: We already check that both key vacant
1625 Ok(unsafe { self.map_vacant_entry(k1, k2) })
1626 }
1627 // Error: Vacant key #1 of type K1 and occupied key # 2 of type K2
1628 Some(_) => Err(EntryError {
1629 error: ErrorKind::VacantK1AndOccupiedK2,
1630 keys: (k1, k2),
1631 }),
1632 },
1633 Some((key2_exist, _)) => match self.key_map.get(&k2) {
1634 Some(key1_exist) => {
1635 return if k1 == *key1_exist && k2 == *key2_exist {
1636 // SAFETY: We already check that both key exist and refer to the same value
1637 Ok(unsafe { self.map_occupied_entry(k1, k2) })
1638 } else {
1639 // Error: key #1 and key # 2 refer to different entries / values
1640 Err(EntryError {
1641 error: ErrorKind::KeysPointsToDiffEntries,
1642 keys: (k1, k2),
1643 })
1644 };
1645 }
1646 None => Err(EntryError {
1647 error: ErrorKind::OccupiedK1AndVacantK2,
1648 keys: (k1, k2),
1649 }),
1650 },
1651 }
1652 }
1653
1654 // This function used only inside this crate. Return Entry::Occupied
1655 // because we know exactly that both entry are occupied
1656 #[inline(always)]
1657 unsafe fn map_occupied_entry(&mut self, k1: K1, k2: K2) -> Entry<'_, K1, K2, V> {
1658 let raw_v = self.value_map.entry(k1);
1659 let raw_k = self.key_map.entry(k2);
1660 match raw_v {
1661 hash_map::Entry::Occupied(base_v) => match raw_k {
1662 hash_map::Entry::Occupied(base_k) => {
1663 Entry::Occupied(OccupiedEntry { base_v, base_k })
1664 }
1665 _ => unreachable_unchecked(),
1666 },
1667 _ => unreachable_unchecked(),
1668 }
1669 }
1670
1671 // This function used only inside this crate. Return Entry::Vacant
1672 // because we know exactly that both entry are vacant
1673 #[inline(always)]
1674 unsafe fn map_vacant_entry(&mut self, k1: K1, k2: K2) -> Entry<'_, K1, K2, V> {
1675 let raw_v = self.value_map.entry(k1);
1676 let raw_k = self.key_map.entry(k2);
1677 match raw_v {
1678 hash_map::Entry::Vacant(base_v) => match raw_k {
1679 hash_map::Entry::Vacant(base_k) => Entry::Vacant(VacantEntry { base_v, base_k }),
1680 _ => unreachable_unchecked(),
1681 },
1682 _ => unreachable_unchecked(),
1683 }
1684 }
1685
1686 /// Inserts given keys and value into the map **`without checking`**. Update the value
1687 /// if key #1 of type `K1` already presents with returning old value.
1688 ///
1689 /// If the map did not have these keys present, [`None`] is returned.
1690 ///
1691 /// # Warning
1692 ///
1693 /// **Using this method can lead to unsynchronization between key #1 and key #1,
1694 /// so that they can refer to different values.** It also can lead to different
1695 /// quantity of keys, so that quantity of keys #2 `K2` can be ***less*** than
1696 /// quantity of keys #1 `K1`.
1697 ///
1698 /// If the map did have these keys vacant or **present** and **both keys refer to
1699 /// the same value** it is ***Ok***, the value is updated, and the old value is
1700 /// returned inside `Some(V)` variant.
1701 ///
1702 /// **But** for this method, it doesn't matter if key # 2 exists or not,
1703 /// it returns updated value also if the map contains only key #1.
1704 /// It is ***because*** this method **doesn't check** that:
1705 /// - key #1 is vacant, but key #2 already exists with some value;
1706 /// - key #1 already exists with some value, but key #2 is vacant;
1707 /// - both key #1 and key #2 already exist with some values, but
1708 /// point to different entries (values).
1709 ///
1710 /// The keys are not updated, though; this matters for types that can
1711 /// be `==` without being identical. See the [std module-level documentation]
1712 /// for more.
1713 ///
1714 /// # Note
1715 ///
1716 /// Using this method is cheaper than using another insertion
1717 /// [`entry`](DHashMap::entry), [`insert`](DHashMap::insert) and
1718 /// [`try_insert`](DHashMap::try_insert) methods.
1719 ///
1720 /// Links between keys #1 `K1` and the values that they refer are adequate.
1721 /// **Unsynchronization** between key #1 and key #2, lead only to that the key # 2
1722 /// may refer to unexpected value.
1723 ///
1724 /// It is recommended to use this method only if you are sure that
1725 /// key #1 and key #2 are unique. For example if key #1 of type `K1` is generated
1726 /// automatically and you check only that there is no key #2 of type `K2`.
1727 ///
1728 /// [std module-level documentation]: std::collections#insert-and-complex-keys
1729 ///
1730 /// # Examples
1731 ///
1732 /// ```
1733 /// use double_map::DHashMap;
1734 /// use core::hash::Hash;
1735 ///
1736 /// let mut map = DHashMap::new();
1737 ///
1738 /// // Returns None if keys are vacant
1739 /// assert_eq!(map.insert_unchecked(1, "a", "One"), None);
1740 /// assert_eq!(map.is_empty(), false);
1741 ///
1742 /// // If the map did have these keys present, the value is updated,
1743 /// // and the old value is returned inside `Some(V)` variants
1744 /// map.insert_unchecked(2, "b", "Two");
1745 /// assert_eq!(map.insert_unchecked(2, "b", "Second"), Some("Two"));
1746 /// assert_eq!(map.get_key1(&2), Some(&"Second"));
1747 ///
1748 /// // But method does not care about key #2
1749 /// assert_eq!(map.insert_unchecked(1, "b", "First"), Some("One"));
1750 /// // So key # 2 refers to unexpected value, and now we have double second keys
1751 /// // referring to the same value
1752 /// assert_eq!(map.get_key2(&"a"), Some(&"First"));
1753 /// assert_eq!(map.get_key2(&"b"), Some(&"First"));
1754 ///
1755 /// // But it can be safe if you generate one key automatically, and check
1756 /// // existence only other key. It can be for example like that:
1757 /// #[derive(Copy, Clone, PartialEq, Eq, Hash)]
1758 /// pub struct PupilID(usize);
1759 ///
1760 /// pub struct Pupil {
1761 /// name: String
1762 /// }
1763 ///
1764 /// pub struct Class {
1765 /// pupils: DHashMap<PupilID, String, Pupil>,
1766 /// len: usize,
1767 /// }
1768 ///
1769 /// impl Class {
1770 /// pub fn new() -> Class {
1771 /// Self{
1772 /// pupils: DHashMap::new(),
1773 /// len: 0
1774 /// }
1775 /// }
1776 /// pub fn contains_name(&self, name: &String) -> bool {
1777 /// self.pupils.get_key2(name).is_some()
1778 /// }
1779 /// pub fn add_pupil(&mut self, name: String) -> Option<PupilID> {
1780 /// if !self.contains_name(&name) {
1781 /// let len = &mut self.len;
1782 /// let id = PupilID(*len);
1783 /// self.pupils.insert_unchecked( id, name.clone(), Pupil { name } );
1784 /// *len += 1;
1785 /// Some(id)
1786 /// } else {
1787 /// None
1788 /// }
1789 /// }
1790 /// }
1791 /// ```
1792 #[inline]
1793 pub fn insert_unchecked(&mut self, k1: K1, k2: K2, v: V) -> Option<V> {
1794 self.key_map.insert(k2.clone(), k1.clone());
1795 match self.value_map.insert(k1, (k2, v)) {
1796 Some((_, v)) => Some(v),
1797 None => None,
1798 }
1799 }
1800
1801 /// Tries to insert given keys and value into the map. Update the value
1802 /// if keys are already present and refer to the same value with returning
1803 /// old value.
1804 ///
1805 /// If the map did not have these keys present, [`None`] is returned.
1806 ///
1807 /// If the map did have these key **present**, and **both keys refer to
1808 /// the same value**, the value is updated, and the old value is returned
1809 /// inside `Some(Ok(V))` variants. The key is not updated, though; this
1810 /// matters for types that can be `==` without being identical.
1811 /// See the [std module-level documentation] for more.
1812 ///
1813 /// The [`insert`](DHashMap::insert) method returns [`InsertError`] structure
1814 /// (inside of `Some(Err(_))` variants):
1815 /// - when key #1 is vacant, but key #2 already exists with some value;
1816 /// - when key #1 already exists with some value, but key #2 is vacant;
1817 /// - when both key #1 and key #2 already exist with some values, but
1818 /// point to different entries (values).
1819 ///
1820 /// The above mentioned error kinds can be matched through the [`ErrorKind`] enum.
1821 /// Returned [`InsertError`] structure also contains provided keys and value
1822 /// that were not inserted and can be used for another purpose.
1823 ///
1824 /// [std module-level documentation]: std::collections#insert-and-complex-keys
1825 ///
1826 /// # Examples
1827 ///
1828 /// ```
1829 /// use double_map::DHashMap;
1830 /// use double_map::dhash_map::{InsertError, ErrorKind};
1831 /// let mut map = DHashMap::new();
1832 ///
1833 /// // Returns None if keys are vacant
1834 /// assert_eq!(map.insert(1, "a", "One"), None);
1835 /// assert_eq!(map.is_empty(), false);
1836 ///
1837 /// // If the map did have these keys present, and both keys refer to
1838 /// // the same value, the value is updated, and the old value is returned
1839 /// // inside `Some(Ok(V))` variants
1840 /// map.insert(2, "b", "Two");
1841 /// assert_eq!(map.insert(2, "b", "Second"), Some(Ok("Two")));
1842 /// assert_eq!(map.get_key1(&2), Some(&"Second"));
1843 ///
1844 /// // Returns `ErrorKind::OccupiedK1AndVacantK2` if key #1 already
1845 /// // exists with some value, but key #2 is vacant. Error structure
1846 /// // also contains provided keys and value
1847 /// match map.insert(1, "c", "value") {
1848 /// Some(Err(InsertError{ error, keys, value })) => {
1849 /// assert_eq!(error, ErrorKind::OccupiedK1AndVacantK2);
1850 /// assert_eq!(keys, (1, "c"));
1851 /// assert_eq!(value, "value");
1852 /// }
1853 /// _ => unreachable!(),
1854 /// }
1855 ///
1856 /// // Returns `ErrorKind::VacantK1AndOccupiedK2` if key #1 is vacant,
1857 /// // but key #2 already exists with some value.
1858 /// let error_kind = map.insert(3, "a", "value").unwrap().unwrap_err().error;
1859 /// assert_eq!(error_kind, ErrorKind::VacantK1AndOccupiedK2);
1860 ///
1861 /// // Returns `ErrorKind::KeysPointsToDiffEntries` if both
1862 /// // key #1 and key #2 already exist with some values,
1863 /// // but point to different entries (values).
1864 /// let error_kind = map.insert(1, "b", "value").unwrap().unwrap_err().error;
1865 /// assert_eq!(error_kind, ErrorKind::KeysPointsToDiffEntries);
1866 /// ```
1867 #[inline]
1868 pub fn insert(&mut self, k1: K1, k2: K2, v: V) -> Option<Result<V, InsertError<K1, K2, V>>> {
1869 match self.entry(k1, k2) {
1870 Ok(entry) => match entry {
1871 Entry::Occupied(mut entry) => {
1872 let v = entry.insert(v);
1873 Some(Ok(v))
1874 }
1875 Entry::Vacant(entry) => {
1876 entry.insert(v);
1877 None
1878 }
1879 },
1880 Err(EntryError { error, keys }) => Some(Err(InsertError {
1881 error,
1882 keys,
1883 value: v,
1884 })),
1885 }
1886 }
1887
1888 /// Tries to insert given keys and value into the map, and returns
1889 /// a mutable reference to the value in the entry if the map did not
1890 /// have these keys present.
1891 ///
1892 /// If the map did have these keys **present**, and **both keys refer to
1893 /// the same value**, ***nothing*** is updated, and a [`TryInsertError::Occupied`]
1894 /// enum variant error containing [`OccupiedError`] structure is returned.
1895 /// The [`OccupiedError`] contains the occupied entry [`OccupiedEntry`],
1896 /// and the value that was not inserted.
1897 ///
1898 /// The [`try_insert`](DHashMap::try_insert) method return [`InsertError`] structure
1899 /// (inside of [`TryInsertError::Insert`] variant):
1900 /// - when key #1 is vacant, but key #2 already exists with some value;
1901 /// - when key #1 already exists with some value, but key #2 is vacant;
1902 /// - when both key #1 and key #2 already exist with some values, but
1903 /// point to different entries (values).
1904 ///
1905 /// The above mentioned error kinds can be matched through the [`ErrorKind`] enum.
1906 /// Returned [`InsertError`] structure also contains provided keys and value
1907 /// that were not inserted and can be used for another purpose.
1908 ///
1909 /// # Examples
1910 ///
1911 /// ```
1912 /// use double_map::DHashMap;
1913 /// use double_map::dhash_map::{TryInsertError, OccupiedError, InsertError, ErrorKind};
1914 ///
1915 ///
1916 /// let mut map = DHashMap::new();
1917 ///
1918 /// // Returns mutable reference to the value if keys are vacant
1919 /// let value = map.try_insert(1, "a", "One").unwrap();
1920 /// assert_eq!(value, &"One");
1921 /// *value = "First";
1922 /// assert_eq!(map.get_key1(&1), Some(&"First"));
1923 ///
1924 /// // If the map did have these keys present, and both keys refer to
1925 /// // the same value, nothing is updated, and the provided value
1926 /// // is returned inside `Err(TryInsertError::Occupied(_))` variants
1927 /// map.try_insert(2, "b", "Two");
1928 /// match map.try_insert(2, "b", "Second") {
1929 /// Err(error) => match error {
1930 /// TryInsertError::Occupied(OccupiedError{ entry, value }) => {
1931 /// assert_eq!(entry.keys(), (&2, &"b"));
1932 /// assert_eq!(entry.get(), &"Two");
1933 /// assert_eq!(value, "Second");
1934 /// }
1935 /// _ => unreachable!(),
1936 /// }
1937 /// _ => unreachable!(),
1938 /// }
1939 /// assert_eq!(map.get_key1(&2), Some(&"Two"));
1940 ///
1941 /// // Returns `ErrorKind::OccupiedK1AndVacantK2` if key #1 already
1942 /// // exists with some value, but key #2 is vacant. Error structure
1943 /// // also contains provided keys and value
1944 /// match map.try_insert(1, "c", "value") {
1945 /// Err(error) => match error {
1946 /// TryInsertError::Insert(InsertError{ error, keys, value }) => {
1947 /// assert_eq!(error, ErrorKind::OccupiedK1AndVacantK2);
1948 /// assert_eq!(keys, (1, "c"));
1949 /// assert_eq!(value, "value");
1950 /// }
1951 /// _ => unreachable!()
1952 /// }
1953 /// _ => unreachable!(),
1954 /// }
1955 ///
1956 /// // Returns `ErrorKind::VacantK1AndOccupiedK2` if key #1 is vacant,
1957 /// // but key #2 already exists with some value.
1958 /// match map.try_insert(3, "a", "value") {
1959 /// Err(error) => match error {
1960 /// TryInsertError::Insert(InsertError{ error, .. }) => {
1961 /// assert_eq!(error, ErrorKind::VacantK1AndOccupiedK2);
1962 /// }
1963 /// _ => unreachable!()
1964 /// }
1965 /// _ => unreachable!(),
1966 /// }
1967 ///
1968 /// // Returns `ErrorKind::KeysPointsToDiffEntries` if both
1969 /// // key #1 and key #2 already exist with some values,
1970 /// // but point to different entries (values).
1971 /// match map.try_insert(1, "b", "value") {
1972 /// Err(error) => match error {
1973 /// TryInsertError::Insert(InsertError{ error, .. }) => {
1974 /// assert_eq!(error, ErrorKind::KeysPointsToDiffEntries);
1975 /// }
1976 /// _ => unreachable!()
1977 /// }
1978 /// _ => unreachable!(),
1979 /// }
1980 /// ```
1981 #[inline]
1982 pub fn try_insert(
1983 &mut self,
1984 k1: K1,
1985 k2: K2,
1986 v: V,
1987 ) -> Result<&mut V, TryInsertError<K1, K2, V>> {
1988 match self.entry(k1, k2) {
1989 Ok(entry) => match entry {
1990 Entry::Occupied(entry) => {
1991 Err(TryInsertError::Occupied(OccupiedError { entry, value: v }))
1992 }
1993 Entry::Vacant(entry) => Ok(entry.insert(v)),
1994 },
1995 Err(EntryError { error, keys }) => Err(TryInsertError::Insert(InsertError {
1996 error,
1997 keys,
1998 value: v,
1999 })),
2000 }
2001 }
2002}
2003
2004/// Create a `DHashMap<K1, K2, V, `[`RandomState`](std::collections::hash_map::RandomState)`>`
2005/// from a list of sequentially given keys and values.
2006///
2007/// Input data list must follow one of these rules:
2008/// - `K1, K2 => V, K1, K2 => V` ... and so on;
2009/// - `(K1, K2) => V, (K1, K2) => V` ... and so on.
2010///
2011/// Last comma separator can be omitted.
2012/// If this macros is called without arguments, i.e. like
2013/// ```
2014/// # use double_map::{DHashMap, dhashmap};
2015/// let map: DHashMap<i32, String, String> = dhashmap![];
2016/// ```
2017/// it is equivalent to [`DHashMap::new()`] function
2018///
2019/// # Examples
2020///
2021/// ```
2022/// use double_map::{DHashMap, dhashmap};
2023///
2024/// // Calling macros without arguments is equivalent to DHashMap::new() function
2025/// let _map0: DHashMap<i32, i32, i32> = dhashmap![];
2026///
2027/// let map = dhashmap!{
2028/// 1, "a" => "One",
2029/// 2, "b" => "Two", // last comma separator can be omitted
2030/// };
2031///
2032/// assert_eq!(map.get_key1(&1), Some(&"One"));
2033/// assert_eq!(map.get_key1(&2), Some(&"Two"));
2034/// assert_eq!(map.get_key2(&"a"), Some(&"One"));
2035/// assert_eq!(map.get_key2(&"b"), Some(&"Two"));
2036///
2037/// let map2 = dhashmap!{
2038/// (3, "c") => "Three",
2039/// (4, "d") => "Four" // last comma separator can be omitted
2040/// };
2041///
2042/// assert_eq!(map2.get_key1(&3), Some(&"Three"));
2043/// assert_eq!(map2.get_key1(&4), Some(&"Four"));
2044/// assert_eq!(map2.get_key2(&"c"), Some(&"Three"));
2045/// assert_eq!(map2.get_key2(&"d"), Some(&"Four"));
2046/// ```
2047#[macro_export]
2048macro_rules! dhashmap {
2049 () => (DHashMap::new());
2050 ($($key1:expr, $key2:expr => $value:expr),+ $(,)?) => (
2051 DHashMap::<_, _, _, std::collections::hash_map::RandomState>::from_iter([$(($key1, $key2, $value)),+])
2052 );
2053 ($(($key1:expr, $key2:expr) => $value:expr),+ $(,)?) => (
2054 DHashMap::<_, _, _, std::collections::hash_map::RandomState>::from_iter([$(($key1, $key2, $value)),+])
2055 );
2056}
2057
2058/// Equality comparisons which are
2059/// [partial equivalence relations](https://en.wikipedia.org/wiki/Partial_equivalence_relation).
2060///
2061/// `x.eq(y)` can also be written `x == y`, and `x.ne(y)` can be written `x != y`.
2062///
2063/// ## Note
2064///
2065/// Internally [`DHashMap`] use two [`HashMap`](`std::collections::HashMap`). One of type
2066/// `HashMap<K1, (K2, V)>` to hold the `(K2, V)` tuple, and second one of type
2067/// `HashMap<K2, K1>` just for holding the primary key of type `K1`.
2068///
2069/// Two maps `m: DHashMap<K1, K2, V, S>` and `n: DHashMap<K1, K2, V, S>` may be equal `m == n`
2070/// only if (a) both `HashMap<K1, (K2, V)>` equal each other and (b) both `HashMap<K2, K1>`
2071/// also equal each other.
2072///
2073/// This means that, if you previously used [`insert_unchecked`](DHashMap::insert_unchecked) method,
2074/// this equality comparisons can return `false` in case of **unsynchronization**
2075/// between first keys of type `K1` and second keys of type `K2`. See
2076/// [`insert_unchecked`](DHashMap::insert_unchecked) method documentation for more.
2077///
2078/// # Examples
2079///
2080/// ```
2081/// use double_map::{DHashMap, dhashmap};
2082///
2083/// let mut map1: DHashMap<i32, &str, &str> = dhashmap!{
2084/// 1, "a" => "One",
2085/// 2, "b" => "Two",
2086/// 3, "c" => "Three",
2087/// };
2088///
2089/// let mut map2: DHashMap<i32, &str, &str> = dhashmap!{
2090/// 1, "a" => "One",
2091/// 2, "b" => "Two",
2092/// 3, "c" => "Three",
2093/// };
2094/// // Now map1 and map2 equal each other
2095/// assert_eq!(map1, map2);
2096///
2097/// // But insert_unchecked method does not care that two keys refer to the same value,
2098/// map2.insert_unchecked(1, "b", "One");
2099/// // so key # 2 refers to unexpected value, and now we have double second keys
2100/// // referring to the same value
2101/// assert_eq!(map2.get_key2(&"a"), Some(&"One"));
2102/// assert_eq!(map2.get_key2(&"b"), Some(&"One"));
2103///
2104/// // So that two map don't equal each other,
2105/// assert_ne!(map1, map2);
2106/// // even if all values and first keys equal each other
2107/// assert_eq!(map1.get_key1(&1), map2.get_key1(&1));
2108/// assert_eq!(map1.get_key1(&2), map2.get_key1(&2));
2109/// assert_eq!(map1.get_key1(&3), map2.get_key1(&3));
2110/// ```
2111impl<K1, K2, V, S> PartialEq for DHashMap<K1, K2, V, S>
2112where
2113 K1: Eq + Hash,
2114 K2: Eq + Hash,
2115 V: PartialEq,
2116 S: BuildHasher,
2117{
2118 fn eq(&self, other: &DHashMap<K1, K2, V, S>) -> bool {
2119 let DHashMap {
2120 value_map: lv_map,
2121 key_map: lk_map,
2122 } = self;
2123 let DHashMap {
2124 value_map: rv_map,
2125 key_map: rk_map,
2126 } = other;
2127 if lv_map.len() != rv_map.len() && lk_map.len() != rk_map.len() {
2128 return false;
2129 }
2130 lv_map
2131 .iter()
2132 .all(|(k1, tuple)| rv_map.get(k1).map_or(false, |tup| *tuple == *tup))
2133 && lk_map
2134 .iter()
2135 .all(|(k1, k2)| rk_map.get(k1).map_or(false, |k| *k2 == *k))
2136 }
2137}
2138
2139impl<K1, K2, V, S> Eq for DHashMap<K1, K2, V, S>
2140where
2141 K1: Eq + Hash,
2142 K2: Eq + Hash,
2143 V: Eq,
2144 S: BuildHasher,
2145{
2146}
2147
2148/// Creates an empty `DHashMap<K1, K2, V, S>`, with the `Default` value for the hasher.
2149impl<K1, K2, V, S> Default for DHashMap<K1, K2, V, S>
2150where
2151 S: Default + Clone,
2152{
2153 /// Creates an empty `DHashMap<K1, K2, V, S>`, with the `Default` value for the hasher.
2154 ///
2155 /// # Examples
2156 ///
2157 /// ```
2158 /// use double_map::DHashMap;
2159 /// use std::collections::hash_map::RandomState;
2160 ///
2161 /// // You need to specify all types of DHashMap, including hasher.
2162 /// // Created map is empty and don't allocate memory
2163 /// let map: DHashMap<u32, String, String, RandomState> = Default::default();
2164 /// assert_eq!(map.capacity(), 0);
2165 /// let map: DHashMap<u32, String, String, RandomState> = DHashMap::default();
2166 /// assert_eq!(map.capacity(), 0);
2167 /// ```
2168 #[inline]
2169 fn default() -> DHashMap<K1, K2, V, S> {
2170 DHashMap::with_hasher(Default::default())
2171 }
2172}
2173
2174/// Get a reference to the value through indexing operations (`DHashMap[index]`)
2175/// in immutable contexts.
2176impl<K1, K2, Q: ?Sized, V, S> Index<&Q> for DHashMap<K1, K2, V, S>
2177where
2178 K1: Eq + Hash + Borrow<Q>,
2179 K2: Eq + Hash,
2180 Q: Eq + Hash,
2181 S: BuildHasher,
2182{
2183 type Output = V;
2184
2185 /// Returns a reference to the value corresponding to the supplied primary key `(key #1)`.
2186 ///
2187 /// The key may be any borrowed form of the map's key type, but
2188 /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
2189 /// the key type.
2190 ///
2191 /// # Panics
2192 ///
2193 /// Panics if the key is not present in the `DHashMap`.
2194 ///
2195 /// # Examples
2196 ///
2197 /// ```
2198 /// use double_map::{DHashMap, dhashmap};
2199 ///
2200 /// let map = dhashmap!{
2201 /// 1, "a" => "One",
2202 /// 2, "b" => "Two",
2203 /// };
2204 ///
2205 /// assert_eq!(map[&1], "One");
2206 /// assert_eq!(map[&2], "Two");
2207 /// ```
2208 #[inline]
2209 fn index(&self, key: &Q) -> &V {
2210 self.get_key1(key).expect("no entry found for key")
2211 }
2212}
2213
2214/// Create a new `DHashMap<K1, K2, V, `[`RandomState`](std::collections::hash_map::RandomState)`>`
2215/// from an array list of sequentially given keys and values.
2216impl<K1, K2, V, const N: usize> From<[(K1, K2, V); N]>
2217 for DHashMap<K1, K2, V, hash_map::RandomState>
2218where
2219 K1: Eq + Hash + Clone,
2220 K2: Eq + Hash + Clone,
2221{
2222 /// # Examples
2223 ///
2224 /// ```
2225 /// use double_map::DHashMap;
2226 ///
2227 /// let map1 = DHashMap::from([(1, 2, 3), (4, 5, 6)]);
2228 /// let map2: DHashMap<_, _, _> = [(1, 2, 3), (4, 5, 6)].into();
2229 /// assert_eq!(map1, map2);
2230 /// ```
2231 fn from(arr: [(K1, K2, V); N]) -> Self {
2232 Self::from_iter(arr)
2233 }
2234}
2235
2236/// Creates an new `DHashMap<K1, K2, V, S>`, with the `Default` value
2237/// for the hasher from from an iterator.
2238impl<K1, K2, V, S> FromIterator<(K1, K2, V)> for DHashMap<K1, K2, V, S>
2239where
2240 K1: Eq + Hash + Clone,
2241 K2: Eq + Hash + Clone,
2242 S: BuildHasher + Default + Clone,
2243{
2244 /// Creates an new `DHashMap<K1, K2, V, S>`, with the `Default` value
2245 /// for the hasher from from an iterator.
2246 ///
2247 /// You need to specify the type of `hasher`
2248 ///
2249 /// # Examples
2250 ///
2251 /// ```
2252 /// use double_map::DHashMap;
2253 /// use std::collections::hash_map::RandomState;
2254 ///
2255 /// let mut number = 0;
2256 /// let some_iter = std::iter::repeat_with(move || {
2257 /// number +=1;
2258 /// (number, number, number * 10)
2259 /// }).take(5);
2260 /// // You need to specify hasher
2261 /// let map: DHashMap<_, _, _, RandomState> = DHashMap::from_iter(some_iter.clone());
2262 /// assert_eq!(map.get_key1(&1), Some(&10));
2263 /// assert_eq!(map.get_key1(&5), Some(&50));
2264 /// assert_eq!(map.get_key1(&6), None);
2265 ///
2266 /// let some_vec: Vec<_> = some_iter.collect();
2267 /// let map: DHashMap<_, _, _, RandomState> = DHashMap::from_iter(some_vec);
2268 /// assert_eq!(map.get_key1(&1), Some(&10));
2269 /// assert_eq!(map.get_key1(&5), Some(&50));
2270 /// assert_eq!(map.get_key1(&6), None);
2271 ///
2272 /// let some_arr = [(1, 1, 10), (2, 2, 20), (3, 3, 30), (4, 4, 40), (5, 5, 50)];
2273 /// let map: DHashMap<_, _, _, RandomState> = DHashMap::from_iter(some_arr);
2274 /// assert_eq!(map.get_key1(&1), Some(&10));
2275 /// assert_eq!(map.get_key1(&5), Some(&50));
2276 /// assert_eq!(map.get_key1(&6), None);
2277 /// ```
2278 fn from_iter<T: IntoIterator<Item = (K1, K2, V)>>(iter: T) -> DHashMap<K1, K2, V, S> {
2279 let mut map = DHashMap::with_hasher(Default::default());
2280 map.extend(iter);
2281 map
2282 }
2283}
2284
2285/// Inserts all new keys and values from the iterator to existing `DHashMap<K1, K2, V, S>`.
2286impl<K1, K2, V, S> Extend<(K1, K2, V)> for DHashMap<K1, K2, V, S>
2287where
2288 K1: Eq + Hash + Clone,
2289 K2: Eq + Hash + Clone,
2290 S: BuildHasher,
2291{
2292 /// Inserts all new keys and values from the iterator to existing `DHashMap<K1, K2, V, S>`.
2293 ///
2294 /// Replace values with existing keys with new values returned from the iterator.
2295 ///
2296 /// # Examples
2297 ///
2298 /// ```
2299 /// use double_map::DHashMap;
2300 ///
2301 /// // Let's create `DHashMap` with std::collections::hash_map::RandomState hasher
2302 /// let mut map = DHashMap::new();
2303 /// map.insert(1, 1, 999);
2304 ///
2305 /// let mut number = 0;
2306 /// let some_iter = std::iter::repeat_with(move || {
2307 /// number +=1;
2308 /// (number, number, number * 10)
2309 /// }).take(5);
2310 ///
2311 /// // You don't need to specify the hasher
2312 /// map.extend(some_iter);
2313 /// // Replace values with existing keys with new values returned from the iterator.
2314 /// // So that the map.get_key1(&1) doesn't return Some(&999).
2315 /// assert_eq!(map.get_key1(&1), Some(&10));
2316 ///
2317 /// let some_vec: Vec<_> = std::iter::repeat_with(move || {
2318 /// number +=100;
2319 /// (number, number, number * 10)
2320 /// }).take(5).collect();
2321 /// map.extend(some_vec);
2322 ///
2323 /// let some_arr = [(11, 11, 111), (22, 22, 222), (33, 33, 333), (44, 44, 4444), (55, 55, 555)];
2324 /// map.extend(some_arr);
2325 ///
2326 /// // Keys and values from some_iter
2327 /// assert_eq!(map.get_key1(&1), Some(&10));
2328 /// assert_eq!(map.get_key1(&5), Some(&50));
2329 /// assert_eq!(map.get_key1(&6), None);
2330 ///
2331 /// // Keys and values from some_vec
2332 /// assert_eq!(map.get_key1(&100), Some(&1000));
2333 /// assert_eq!(map.get_key1(&500), Some(&5000));
2334 /// assert_eq!(map.get_key1(&600), None);
2335 ///
2336 /// // Keys and values from some_arr
2337 /// assert_eq!(map.get_key1(&11), Some(&111));
2338 /// assert_eq!(map.get_key1(&55), Some(&555));
2339 /// assert_eq!(map.get_key1(&66), None);
2340 /// ```
2341 #[inline]
2342 fn extend<T: IntoIterator<Item = (K1, K2, V)>>(&mut self, iter: T) {
2343 // Keys may be already present or show multiple times in the iterator.
2344 // Reserve the entire hint lower bound if the map is empty.
2345 // Otherwise reserve half the hint (rounded up), so the map
2346 // will only resize twice in the worst case.
2347 let iter = iter.into_iter();
2348 let reserve = if self.is_empty() {
2349 iter.size_hint().0
2350 } else {
2351 (iter.size_hint().0 + 1) / 2
2352 };
2353 self.reserve(reserve);
2354 iter.for_each(move |(k1, k2, v)| {
2355 self.insert(k1, k2, v);
2356 });
2357 }
2358}
2359
2360/// Inserts all new keys and values from the iterator to existing `DHashMap<K1, K2, V, S>`.
2361impl<'a, K1, K2, V, S> Extend<(&'a K1, &'a K2, &'a V)> for DHashMap<K1, K2, V, S>
2362where
2363 K1: Eq + Hash + Copy,
2364 K2: Eq + Hash + Copy,
2365 V: Copy,
2366 S: BuildHasher,
2367{
2368 /// Inserts all new keys and values from the iterator to existing `DHashMap<K1, K2, V, S>`.
2369 ///
2370 /// Replace values with existing keys with new values returned from the iterator.
2371 /// The keys and values must implement [`Copy`] trait.
2372 ///
2373 /// # Examples
2374 ///
2375 /// ```
2376 /// use double_map::DHashMap;
2377 ///
2378 /// // Let's create `DHashMap` with std::collections::hash_map::RandomState hasher
2379 /// let mut map = DHashMap::new();
2380 /// map.insert(1, 1, 999);
2381 ///
2382 /// let mut number = 0;
2383 /// let some_vec: Vec<_> = std::iter::repeat_with(move || {
2384 /// number +=1;
2385 /// (number, number, number * 10)
2386 /// }).take(5).collect();
2387 ///
2388 /// // You don't need to specify the hasher
2389 /// let some_iter = some_vec.iter().map(|(k1, k2, v)| (k1, k2, v));
2390 /// map.extend(some_iter);
2391 ///
2392 /// // Replace values with existing keys with new values returned from the iterator.
2393 /// // So that the map.get_key1(&1) doesn't return Some(&999).
2394 /// assert_eq!(map.get_key1(&1), Some(&10));
2395 /// assert_eq!(map.get_key1(&5), Some(&50));
2396 /// assert_eq!(map.get_key1(&6), None);
2397 ///
2398 /// // Created vector are still can be used
2399 /// assert_eq!(some_vec[4], (5, 5, 50));
2400 ///
2401 /// // Also you can use for extending already existing map
2402 /// let mut map2 = DHashMap::new();
2403 /// map2.extend(&map);
2404 /// assert_eq!(map, map2);
2405 /// ```
2406 #[inline]
2407 fn extend<T: IntoIterator<Item = (&'a K1, &'a K2, &'a V)>>(&mut self, iter: T) {
2408 self.extend(iter.into_iter().map(|(&k1, &k2, &v)| (k1, k2, v)))
2409 }
2410}
2411
2412/// Inserts all new keys and values from the iterator to existing `DHashMap<K1, K2, V, S>`.
2413impl<'a, K1, K2, V, S> Extend<&'a (K1, K2, V)> for DHashMap<K1, K2, V, S>
2414where
2415 K1: Eq + Hash + Copy,
2416 K2: Eq + Hash + Copy,
2417 V: Copy,
2418 S: BuildHasher,
2419{
2420 /// Inserts all new keys and values from the iterator to existing `DHashMap<K1, K2, V, S>`.
2421 ///
2422 /// Replace values with existing keys with new values returned from the iterator.
2423 /// The keys and values must implement [`Copy`] trait.
2424 ///
2425 /// # Examples
2426 ///
2427 /// ```
2428 /// use double_map::DHashMap;
2429 ///
2430 /// // Let's create `DHashMap` with std::collections::hash_map::RandomState hasher
2431 /// let mut map = DHashMap::new();
2432 /// map.insert(1, 1, 999);
2433 ///
2434 /// let mut number = 0;
2435 /// let some_vec: Vec<_> = std::iter::repeat_with(move || {
2436 /// number +=1;
2437 /// (number, number, number * 10)
2438 /// }).take(5).collect();
2439 ///
2440 /// // You don't need to specify the hasher
2441 /// map.extend(&some_vec);
2442 ///
2443 /// // Replace values with existing keys with new values returned from the iterator.
2444 /// // So that the map.get_key1(&1) doesn't return Some(&999).
2445 /// assert_eq!(map.get_key1(&1), Some(&10));
2446 /// assert_eq!(map.get_key1(&5), Some(&50));
2447 /// assert_eq!(map.get_key1(&6), None);
2448 ///
2449 /// // And created vector are still can be used.
2450 /// assert_eq!(some_vec[4], (5, 5, 50));
2451 /// ```
2452 #[inline]
2453 fn extend<T: IntoIterator<Item = &'a (K1, K2, V)>>(&mut self, iter: T) {
2454 self.extend(iter.into_iter().map(|&(k1, k2, v)| (k1, k2, v)))
2455 }
2456}
2457
2458/// An iterator over the entries of a `DHashMap` in arbitrary order.
2459/// The iterator element is tuple of type `(&'a K1, &'a K2, &'a V)`.
2460///
2461/// This `struct` is created by the [`iter`](DHashMap::iter) method
2462/// on [`DHashMap`]. See its documentation for more.
2463///
2464/// # Example
2465///
2466/// ```
2467/// use double_map::{DHashMap, dhashmap};
2468///
2469/// let map = dhashmap!{
2470/// 1, "a" => "One",
2471/// 2, "b" => "Two",
2472/// 3, "c" => "Three",
2473/// };
2474///
2475/// let mut iter = map.iter();
2476/// let mut vec = vec![iter.next(), iter.next(), iter.next()];
2477///
2478/// // The `Iter` iterator produces tuples in arbitrary order, so the
2479/// // tuples must be sorted to test them against a sorted array.
2480/// vec.sort_unstable();
2481/// assert_eq!(vec, [Some((&1, &"a", &"One")), Some((&2, &"b", &"Two")), Some((&3, &"c", &"Three"))]);
2482///
2483/// // It is fused iterator
2484/// assert_eq!(iter.next(), None);
2485/// assert_eq!(iter.next(), None);
2486/// ```
2487#[derive(Clone, Debug)]
2488pub struct Iter<'a, K1: 'a, K2: 'a, V: 'a> {
2489 base: hash_map::Iter<'a, K1, (K2, V)>,
2490}
2491
2492impl<'a, K1, K2, V> Iterator for Iter<'a, K1, K2, V> {
2493 type Item = (&'a K1, &'a K2, &'a V);
2494
2495 #[inline]
2496 fn next(&mut self) -> Option<(&'a K1, &'a K2, &'a V)> {
2497 // We do not use Option::map for performance purpose
2498 match self.base.next() {
2499 Some((k1, (k2, val))) => Some((k1, k2, val)),
2500 None => None,
2501 }
2502 }
2503 #[inline]
2504 fn size_hint(&self) -> (usize, Option<usize>) {
2505 self.base.size_hint()
2506 }
2507}
2508
2509impl<K1, K2, V> ExactSizeIterator for Iter<'_, K1, K2, V> {
2510 #[inline]
2511 fn len(&self) -> usize {
2512 self.base.len()
2513 }
2514}
2515
2516impl<K1, K2, V> FusedIterator for Iter<'_, K1, K2, V> {}
2517
2518/// An iterator over the keys of a `DHashMap` in arbitrary order.
2519/// The iterator element is tuple of type `(&'a K1, &'a K2)`.
2520///
2521/// This `struct` is created by the [`keys`](DHashMap::keys) method
2522/// on [`DHashMap`]. See its documentation for more.
2523///
2524/// # Example
2525///
2526/// ```
2527/// use double_map::{DHashMap, dhashmap};
2528///
2529/// let map = dhashmap!{
2530/// 1, "a" => "One",
2531/// 2, "b" => "Two",
2532/// 3, "c" => "Three",
2533/// };
2534///
2535/// let mut keys = map.keys();
2536/// let mut vec = vec![keys.next(), keys.next(), keys.next()];
2537///
2538/// // The `Keys` iterator produces tuples in arbitrary order, so the
2539/// // tuples must be sorted to test them against a sorted array.
2540/// vec.sort_unstable();
2541/// assert_eq!(vec, [Some((&1, &"a")), Some((&2, &"b")), Some((&3, &"c"))]);
2542///
2543/// // It is fused iterator
2544/// assert_eq!(keys.next(), None);
2545/// assert_eq!(keys.next(), None);
2546/// ```
2547#[derive(Clone, Debug)]
2548pub struct Keys<'a, K1: 'a, K2: 'a, V: 'a> {
2549 inner: Iter<'a, K1, K2, V>,
2550}
2551
2552impl<'a, K1, K2, V> Iterator for Keys<'a, K1, K2, V> {
2553 type Item = (&'a K1, &'a K2);
2554
2555 #[inline]
2556 fn next(&mut self) -> Option<(&'a K1, &'a K2)> {
2557 // We do not use Option::map for performance purpose
2558 match self.inner.next() {
2559 Some((k1, k2, _)) => Some((k1, k2)),
2560 None => None,
2561 }
2562 }
2563 #[inline]
2564 fn size_hint(&self) -> (usize, Option<usize>) {
2565 self.inner.size_hint()
2566 }
2567}
2568
2569impl<K1, K2, V> ExactSizeIterator for Keys<'_, K1, K2, V> {
2570 #[inline]
2571 fn len(&self) -> usize {
2572 self.inner.len()
2573 }
2574}
2575
2576impl<K1, K2, V> FusedIterator for Keys<'_, K1, K2, V> {}
2577
2578/// An iterator over the values of a `DHashMap` in arbitrary order.
2579/// The iterator element is `&'a V`.
2580///
2581/// This `struct` is created by the [`values`](DHashMap::values) method
2582/// on [`DHashMap`]. See its documentation for more.
2583///
2584/// # Example
2585///
2586/// ```
2587/// use double_map::{DHashMap, dhashmap};
2588///
2589/// let map = dhashmap!{
2590/// 1, "a" => 10,
2591/// 2, "b" => 20,
2592/// 3, "c" => 30,
2593/// };
2594///
2595/// let mut values = map.values();
2596/// let mut vec = vec![values.next(), values.next(), values.next()];
2597///
2598/// // The `Values` iterator produces values in arbitrary order, so the
2599/// // values must be sorted to test them against a sorted array.
2600/// vec.sort_unstable();
2601/// assert_eq!(vec, [Some(&10), Some(&20), Some(&30)]);
2602///
2603/// // It is fused iterator
2604/// assert_eq!(values.next(), None);
2605/// assert_eq!(values.next(), None);
2606/// ```
2607#[derive(Clone, Debug)]
2608pub struct Values<'a, K1: 'a, K2: 'a, V: 'a> {
2609 inner: Iter<'a, K1, K2, V>,
2610}
2611
2612impl<'a, K1, K2, V> Iterator for Values<'a, K1, K2, V> {
2613 type Item = &'a V;
2614
2615 #[inline]
2616 fn next(&mut self) -> Option<&'a V> {
2617 // We do not use Option::map for performance purpose
2618 match self.inner.next() {
2619 Some((_, _, val)) => Some(val),
2620 None => None,
2621 }
2622 }
2623 #[inline]
2624 fn size_hint(&self) -> (usize, Option<usize>) {
2625 self.inner.size_hint()
2626 }
2627}
2628
2629impl<K1, K2, V> ExactSizeIterator for Values<'_, K1, K2, V> {
2630 #[inline]
2631 fn len(&self) -> usize {
2632 self.inner.len()
2633 }
2634}
2635
2636impl<K1, K2, V> FusedIterator for Values<'_, K1, K2, V> {}
2637
2638/// A mutable iterator over the entries of a `DHashMap` in arbitrary order.
2639/// The iterator element is tuple of type`(&'a K1, &'a K2, &'a mut V)`.
2640///
2641/// This `struct` is created by the [`iter_mut`](DHashMap::iter_mut) method
2642/// on [`DHashMap`]. See its documentation for more.
2643///
2644/// # Example
2645///
2646/// ```
2647/// use double_map::{DHashMap, dhashmap};
2648///
2649/// let mut map = dhashmap!{
2650/// 1, "a" => "One".to_owned(),
2651/// 2, "b" => "Two".to_owned(),
2652/// 3, "c" => "Three".to_owned(),
2653/// };
2654///
2655/// let mut iter = map.iter_mut();
2656/// iter.next().map(|(_, _, v)| v.push_str(" coin"));
2657/// iter.next().map(|(_, _, v)| v.push_str(" coin"));
2658/// iter.next().map(|(_, _, v)| v.push_str(" coin"));
2659///
2660/// // It is fused iterator
2661/// assert_eq!(iter.next(), None);
2662/// assert_eq!(iter.next(), None);
2663///
2664/// assert_eq!(map.get_key1(&1).unwrap(), &"One coin".to_owned() );
2665/// assert_eq!(map.get_key1(&2).unwrap(), &"Two coin".to_owned() );
2666/// assert_eq!(map.get_key1(&3).unwrap(), &"Three coin".to_owned());
2667/// ```
2668#[derive(Debug)]
2669pub struct IterMut<'a, K1: 'a, K2: 'a, V: 'a> {
2670 base: hash_map::IterMut<'a, K1, (K2, V)>,
2671}
2672
2673impl<'a, K1, K2, V> Iterator for IterMut<'a, K1, K2, V> {
2674 type Item = (&'a K1, &'a K2, &'a mut V);
2675
2676 #[inline]
2677 fn next(&mut self) -> Option<(&'a K1, &'a K2, &'a mut V)> {
2678 // We do not use Option::map for performance purpose
2679 match self.base.next() {
2680 Some((k1, (ref k2, val))) => Some((k1, k2, val)),
2681 None => None,
2682 }
2683 }
2684 #[inline]
2685 fn size_hint(&self) -> (usize, Option<usize>) {
2686 self.base.size_hint()
2687 }
2688}
2689
2690impl<K1, K2, V> ExactSizeIterator for IterMut<'_, K1, K2, V> {
2691 #[inline]
2692 fn len(&self) -> usize {
2693 self.base.len()
2694 }
2695}
2696
2697impl<K1, K2, V> FusedIterator for IterMut<'_, K1, K2, V> {}
2698
2699/// A mutable iterator over the values of a `DHashMap` in arbitrary order.
2700/// The iterator element is `&'a mut V`.
2701///
2702/// This `struct` is created by the [`values_mut`](DHashMap::values_mut) method
2703/// on [`DHashMap`]. See its documentation for more.
2704///
2705/// # Example
2706///
2707/// ```
2708/// use double_map::{DHashMap, dhashmap};
2709///
2710/// let mut map = dhashmap!{
2711/// 1, "a" => "One".to_owned(),
2712/// 2, "b" => "Two".to_owned(),
2713/// 3, "c" => "Three".to_owned(),
2714/// };
2715///
2716/// let mut values = map.values_mut();
2717/// values.next().map(|v| v.push_str(" coin"));
2718/// values.next().map(|v| v.push_str(" coin"));
2719/// values.next().map(|v| v.push_str(" coin"));
2720///
2721/// // It is fused iterator
2722/// assert_eq!(values.next(), None);
2723/// assert_eq!(values.next(), None);
2724///
2725/// assert_eq!(map.get_key1(&1).unwrap(), &"One coin".to_owned() );
2726/// assert_eq!(map.get_key1(&2).unwrap(), &"Two coin".to_owned() );
2727/// assert_eq!(map.get_key1(&3).unwrap(), &"Three coin".to_owned());
2728/// ```
2729#[derive(Debug)]
2730pub struct ValuesMut<'a, K1: 'a, K2: 'a, V: 'a> {
2731 inner: IterMut<'a, K1, K2, V>,
2732}
2733
2734impl<'a, K1, K2, V> Iterator for ValuesMut<'a, K1, K2, V> {
2735 type Item = &'a mut V;
2736
2737 #[inline]
2738 fn next(&mut self) -> Option<&'a mut V> {
2739 // We do not use Option::map for performance purpose
2740 match self.inner.next() {
2741 Some((_, _, val)) => Some(val),
2742 None => None,
2743 }
2744 }
2745 #[inline]
2746 fn size_hint(&self) -> (usize, Option<usize>) {
2747 self.inner.size_hint()
2748 }
2749}
2750
2751impl<K1, K2, V> ExactSizeIterator for ValuesMut<'_, K1, K2, V> {
2752 #[inline]
2753 fn len(&self) -> usize {
2754 self.inner.len()
2755 }
2756}
2757
2758impl<K1, K2, V> FusedIterator for ValuesMut<'_, K1, K2, V> {}
2759
2760/// A draining iterator over the entries of a `DHashMap` in arbitrary order.
2761/// The iterator element is tuple of type`(K1, K2, V)`.
2762///
2763/// This `struct` is created by the [`drain`](DHashMap::drain) method
2764/// on [`DHashMap`]. See its documentation for more.
2765///
2766/// # Example
2767///
2768/// ```
2769/// use double_map::{DHashMap, dhashmap};
2770///
2771/// let mut map = dhashmap!{
2772/// 1, "a" => "One",
2773/// 2, "b" => "Two",
2774/// 3, "c" => "Three",
2775/// };
2776///
2777/// let mut drain_iter = map.drain();
2778/// let mut vec = vec![drain_iter.next(), drain_iter.next(), drain_iter.next()];
2779///
2780/// // The `Drain` iterator produces tuples in arbitrary order, so the
2781/// // tuples must be sorted to test them against a sorted array.
2782/// vec.sort_unstable();
2783/// assert_eq!(vec, [Some((1, "a", "One")), Some((2, "b", "Two")), Some((3, "c", "Three"))]);
2784///
2785/// // It is fused iterator
2786/// assert_eq!(drain_iter.next(), None);
2787/// assert_eq!(drain_iter.next(), None);
2788/// ```
2789#[derive(Debug)]
2790pub struct Drain<'a, K1: 'a, K2: 'a, V: 'a> {
2791 base: hash_map::Drain<'a, K1, (K2, V)>,
2792}
2793
2794impl<'a, K1, K2, V> Iterator for Drain<'a, K1, K2, V> {
2795 type Item = (K1, K2, V);
2796
2797 #[inline]
2798 fn next(&mut self) -> Option<(K1, K2, V)> {
2799 match self.base.next() {
2800 Some((key_one, (key_two, value))) => Some((key_one, key_two, value)),
2801 None => None,
2802 }
2803 }
2804 #[inline]
2805 fn size_hint(&self) -> (usize, Option<usize>) {
2806 self.base.size_hint()
2807 }
2808}
2809
2810impl<K1, K2, V> ExactSizeIterator for Drain<'_, K1, K2, V> {
2811 #[inline]
2812 fn len(&self) -> usize {
2813 self.base.len()
2814 }
2815}
2816
2817impl<K1, K2, V> FusedIterator for Drain<'_, K1, K2, V> {}
2818
2819/// An owning iterator over the entries of a `DHashMap`.
2820///
2821/// This `struct` is created by the [`into_iter`] method on [`DHashMap`]
2822/// (provided by the [`IntoIterator`] trait). See its documentation for more.
2823///
2824/// [`into_iter`]: IntoIterator::into_iter
2825/// [`IntoIterator`]: core::iter::IntoIterator
2826///
2827/// # Example
2828///
2829/// ```
2830/// use double_map::{DHashMap, dhashmap};
2831///
2832/// let mut map = dhashmap!{
2833/// 1, "a" => "One",
2834/// 2, "b" => "Two",
2835/// 3, "c" => "Three",
2836/// };
2837///
2838/// let mut iter = map.into_iter();
2839/// let mut vec = vec![iter.next(), iter.next(), iter.next()];
2840///
2841/// // The `IntoIter` iterator produces tuples in arbitrary order, so the
2842/// // tuples must be sorted to test them against a sorted array.
2843/// vec.sort_unstable();
2844/// assert_eq!(vec, [Some((1, "a", "One")), Some((2, "b", "Two")), Some((3, "c", "Three"))]);
2845///
2846/// // It is fused iterator
2847/// assert_eq!(iter.next(), None);
2848/// assert_eq!(iter.next(), None);
2849/// ```
2850#[derive(Debug)]
2851pub struct IntoIter<K1, K2, V> {
2852 base: hash_map::IntoIter<K1, (K2, V)>,
2853}
2854
2855impl<K1, K2, V> Iterator for IntoIter<K1, K2, V> {
2856 type Item = (K1, K2, V);
2857
2858 #[inline]
2859 fn next(&mut self) -> Option<(K1, K2, V)> {
2860 match self.base.next() {
2861 Some((k1, (k2, v))) => Some((k1, k2, v)),
2862 None => None,
2863 }
2864 }
2865 #[inline]
2866 fn size_hint(&self) -> (usize, Option<usize>) {
2867 self.base.size_hint()
2868 }
2869}
2870
2871impl<K1, K2, V> ExactSizeIterator for IntoIter<K1, K2, V> {
2872 #[inline]
2873 fn len(&self) -> usize {
2874 self.base.len()
2875 }
2876}
2877
2878impl<K1, K2, V> FusedIterator for IntoIter<K1, K2, V> {}
2879
2880/// An owning iterator over the keys of a `DHashMap`.
2881///
2882/// This `struct` is created by the [`into_keys`] method on [`DHashMap`].
2883/// See its documentation for more.
2884///
2885/// [`into_keys`]: DHashMap::into_keys
2886///
2887/// # Example
2888///
2889/// ```
2890/// use double_map::{DHashMap, dhashmap};
2891///
2892/// let mut map = dhashmap!{
2893/// 1, "a" => "One",
2894/// 2, "b" => "Two",
2895/// 3, "c" => "Three",
2896/// };
2897///
2898/// let mut keys = map.into_keys();
2899/// let mut vec = vec![keys.next(), keys.next(), keys.next()];
2900///
2901/// // The `IntoKeys` iterator produces keys in arbitrary order, so the
2902/// // keys must be sorted to test them against a sorted array.
2903/// vec.sort_unstable();
2904/// assert_eq!(vec, [Some((1, "a")), Some((2, "b")), Some((3, "c"))]);
2905///
2906/// // It is fused iterator
2907/// assert_eq!(keys.next(), None);
2908/// assert_eq!(keys.next(), None);
2909/// ```
2910#[derive(Debug)]
2911pub struct IntoKeys<K1, K2, V> {
2912 inner: IntoIter<K1, K2, V>,
2913}
2914
2915impl<K1, K2, V> Iterator for IntoKeys<K1, K2, V> {
2916 type Item = (K1, K2);
2917
2918 #[inline]
2919 fn next(&mut self) -> Option<(K1, K2)> {
2920 match self.inner.next() {
2921 Some((k1, k2, _)) => Some((k1, k2)),
2922 None => None,
2923 }
2924 }
2925 #[inline]
2926 fn size_hint(&self) -> (usize, Option<usize>) {
2927 self.inner.size_hint()
2928 }
2929}
2930
2931impl<K1, K2, V> ExactSizeIterator for IntoKeys<K1, K2, V> {
2932 #[inline]
2933 fn len(&self) -> usize {
2934 self.inner.len()
2935 }
2936}
2937
2938impl<K1, K2, V> FusedIterator for IntoKeys<K1, K2, V> {}
2939
2940/// An owning iterator over the values of a `DHashMap`.
2941///
2942/// This `struct` is created by the [`into_values`] method on [`DHashMap`].
2943/// See its documentation for more.
2944///
2945/// [`into_values`]: DHashMap::into_values
2946///
2947/// # Example
2948///
2949/// ```
2950/// use double_map::{DHashMap, dhashmap};
2951///
2952/// let mut map = dhashmap!{
2953/// 1, "One" => "a",
2954/// 2, "Two" => "b",
2955/// 3, "Three" => "c",
2956/// };
2957///
2958/// let mut values = map.into_values();
2959/// let mut vec = vec![values.next(), values.next(), values.next()];
2960///
2961/// // The `IntoValues` iterator produces values in arbitrary order, so
2962/// // the values must be sorted to test them against a sorted array.
2963/// vec.sort_unstable();
2964/// assert_eq!(vec, [Some("a"), Some("b"), Some("c")]);
2965///
2966/// // It is fused iterator
2967/// assert_eq!(values.next(), None);
2968/// assert_eq!(values.next(), None);
2969/// ```
2970#[derive(Debug)]
2971pub struct IntoValues<K1, K2, V> {
2972 inner: IntoIter<K1, K2, V>,
2973}
2974
2975impl<K1, K2, V> Iterator for IntoValues<K1, K2, V> {
2976 type Item = V;
2977
2978 #[inline]
2979 fn next(&mut self) -> Option<V> {
2980 match self.inner.next() {
2981 Some((_, _, v)) => Some(v),
2982 None => None,
2983 }
2984 }
2985 #[inline]
2986 fn size_hint(&self) -> (usize, Option<usize>) {
2987 self.inner.size_hint()
2988 }
2989}
2990
2991impl<K1, K2, V> ExactSizeIterator for IntoValues<K1, K2, V> {
2992 #[inline]
2993 fn len(&self) -> usize {
2994 self.inner.len()
2995 }
2996}
2997
2998impl<K1, K2, V> FusedIterator for IntoValues<K1, K2, V> {}
2999
3000impl<'a, K1, K2, V, S> IntoIterator for &'a DHashMap<K1, K2, V, S> {
3001 type Item = (&'a K1, &'a K2, &'a V);
3002 type IntoIter = Iter<'a, K1, K2, V>;
3003
3004 /// Creates an iterator visiting all keys-value tuples in arbitrary order.
3005 /// The iterator element is tuple of type `(&'a K1, &'a K2, &'a V)`.
3006 ///
3007 /// # Note
3008 ///
3009 /// Created iterator iterates only through the first [`HashMap<K1, (K2, V)>`](`std::collections::HashMap`)
3010 /// which is used underneath of the [`DHashMap`].
3011 ///
3012 /// So that, if you previously used [`insert_unchecked`](DHashMap::insert_unchecked) method,
3013 /// this method can return false second keys (key #2) in case of **unsynchronization**
3014 /// between first keys of type `K1` and second keys of type `K2`. See
3015 /// [`insert_unchecked`](DHashMap::insert_unchecked) and [`iter`](DHashMap::iter)
3016 /// methods documentation for more.
3017 ///
3018 /// # Examples
3019 ///
3020 /// ```
3021 /// use double_map::{DHashMap, dhashmap};
3022 ///
3023 /// let mut map = dhashmap!{
3024 /// "a", 1 => "One",
3025 /// "b", 2 => "Two",
3026 /// "c", 3 => "Three",
3027 /// };
3028 /// assert_eq!(map.len(), 3);
3029 ///
3030 /// for (key1, key2, value) in &map {
3031 /// println!("key1: {}, key2: {}, value: {}", key1, key2, value);
3032 /// assert!(
3033 /// (key1, key2, value) == (&"a", &1, &"One") ||
3034 /// (key1, key2, value) == (&"b", &2, &"Two") ||
3035 /// (key1, key2, value) == (&"c", &3, &"Three")
3036 /// );
3037 /// }
3038 ///
3039 /// assert_eq!(map.len(), 3);
3040 /// ```
3041 fn into_iter(self) -> Iter<'a, K1, K2, V> {
3042 self.iter()
3043 }
3044}
3045
3046impl<'a, K1, K2, V, S> IntoIterator for &'a mut DHashMap<K1, K2, V, S> {
3047 type Item = (&'a K1, &'a K2, &'a mut V);
3048 type IntoIter = IterMut<'a, K1, K2, V>;
3049
3050 /// Creates an iterator visiting all keys-value tuples in arbitrary order,
3051 /// with mutable references to the values. The iterator element is tuple
3052 /// of type `(&'a K1, &'a K2, &'a mut V)`.
3053 ///
3054 /// # Note
3055 ///
3056 /// Created iterator iterates only through the first [`HashMap<K1, (K2, V)>`](`std::collections::HashMap`)
3057 /// which is used underneath of the [`DHashMap`].
3058 ///
3059 /// So that, if you previously used [`insert_unchecked`](DHashMap::insert_unchecked) method,
3060 /// this method can return false second keys (key #2) in case of **unsynchronization**
3061 /// between first keys of type `K1` and second keys of type `K2`. See
3062 /// [`insert_unchecked`](DHashMap::insert_unchecked) and [`iter_mut`](DHashMap::iter_mut)
3063 /// methods documentation for more.
3064 ///
3065 /// # Examples
3066 ///
3067 /// ```
3068 /// use double_map::{DHashMap, dhashmap};
3069 ///
3070 /// let mut map = dhashmap!{
3071 /// "a", "One" => 1,
3072 /// "b", "Two" => 2,
3073 /// "c", "Three" => 3,
3074 /// };
3075 ///
3076 /// assert_eq!(map.len(), 3);
3077 ///
3078 /// // Update all values
3079 /// for (_, _, value) in &mut map {
3080 /// *value *= 2;
3081 /// }
3082 ///
3083 /// for (key1, key2, value) in &map {
3084 /// println!("key1: {}, key2: {}, value: {}", key1, key2, value);
3085 /// assert!(
3086 /// (key1, key2, value) == (&"a", &"One", &2) ||
3087 /// (key1, key2, value) == (&"b", &"Two", &4) ||
3088 /// (key1, key2, value) == (&"c", &"Three", &6)
3089 /// );
3090 /// }
3091 ///
3092 /// assert_eq!(map.len(), 3);
3093 /// ```
3094 fn into_iter(self) -> IterMut<'a, K1, K2, V> {
3095 self.iter_mut()
3096 }
3097}
3098
3099impl<K1, K2, V, S> IntoIterator for DHashMap<K1, K2, V, S> {
3100 type Item = (K1, K2, V);
3101 type IntoIter = IntoIter<K1, K2, V>;
3102
3103 /// Creates a consuming iterator, that is, one that moves each keys-value
3104 /// tuple out of the map in arbitrary order. The map cannot be used after
3105 /// calling this.
3106 ///
3107 /// # Note
3108 ///
3109 /// Created iterator contains only content of the first [`HashMap<K1, (K2, V)>`](`std::collections::HashMap`)
3110 /// which is used underneath of the [`DHashMap`].
3111 ///
3112 /// So that, if you previously used [`insert_unchecked`](DHashMap::insert_unchecked) method,
3113 /// this method can return false second keys (key #2) in case of **unsynchronization**
3114 /// between first keys of type `K1` and second keys of type `K2`. See
3115 /// [`insert_unchecked`](DHashMap::insert_unchecked) method documentation for more.
3116 ///
3117 /// # Examples
3118 ///
3119 /// ```
3120 /// use double_map::{DHashMap, dhashmap};
3121 ///
3122 /// let mut map = dhashmap!{
3123 /// 1, "a" => "One",
3124 /// 2, "b" => "Two",
3125 /// 3, "c" => "Three",
3126 /// };
3127 ///
3128 /// // Not possible with .iter()
3129 /// let mut vec: Vec<(i32, &str, &str)> = map.into_iter().collect();
3130 /// // The `IntoIter` iterator produces tuples in arbitrary order, so
3131 /// // the tuples must be sorted to test them against a sorted array.
3132 /// vec.sort_unstable();
3133 /// assert_eq!(vec, [(1, "a", "One"), (2, "b", "Two"), (3, "c", "Three")])
3134 /// ```
3135 fn into_iter(self) -> IntoIter<K1, K2, V> {
3136 IntoIter {
3137 base: self.value_map.into_iter(),
3138 }
3139 }
3140}
3141
3142/// A view into an occupied entry in a [`DHashMap`].
3143/// It is part of the [`Entry`] enum and [`OccupiedError`] struct.
3144#[derive(Debug)]
3145pub struct OccupiedEntry<'a, K1: 'a, K2: 'a, V: 'a> {
3146 base_v: hash_map::OccupiedEntry<'a, K1, (K2, V)>,
3147 base_k: hash_map::OccupiedEntry<'a, K2, K1>,
3148}
3149
3150impl<'a, K1, K2, V> OccupiedEntry<'a, K1, K2, V> {
3151 /// Gets a reference to the key #1 of type `K1` in the entry.
3152 ///
3153 /// # Examples
3154 ///
3155 /// ```
3156 /// use double_map::DHashMap;
3157 /// use double_map::dhash_map::Entry;
3158 ///
3159 /// let mut map: DHashMap<&str, u32, i32> = DHashMap::new();
3160 /// map.insert("poneyland", 0, 12);
3161 ///
3162 /// if let Ok(entry) = map.entry("poneyland", 0) {
3163 /// match entry {
3164 /// Entry::Occupied(oc_entry) => {
3165 /// assert_eq!(oc_entry.key1(), &"poneyland");
3166 /// }
3167 /// Entry::Vacant(_) => panic!("Something go wrong!!!")
3168 /// }
3169 /// }
3170 /// ```
3171 #[inline]
3172 pub fn key1(&self) -> &K1 {
3173 self.base_v.key()
3174 }
3175
3176 /// Gets a reference to the key #2 of type `K2` in the entry.
3177 ///
3178 /// # Examples
3179 ///
3180 /// ```
3181 /// use double_map::DHashMap;
3182 /// use double_map::dhash_map::Entry;
3183 ///
3184 /// let mut map: DHashMap<&str, u32, i32> = DHashMap::new();
3185 /// map.insert("poneyland", 0, 12);
3186 ///
3187 /// if let Ok(entry) = map.entry("poneyland", 0) {
3188 /// match entry {
3189 /// Entry::Occupied(oc_entry) => {
3190 /// assert_eq!(oc_entry.key2(), &0);
3191 /// }
3192 /// Entry::Vacant(_) => panic!("Something go wrong!!!")
3193 /// }
3194 /// }
3195 /// ```
3196 #[inline]
3197 pub fn key2(&self) -> &K2 {
3198 self.base_k.key()
3199 }
3200
3201 /// Gets a reference to the keys of type `K1` and `K2` in the entry.
3202 /// Return tuple of type `(&'a K1, &'a K2)`.
3203 ///
3204 /// # Examples
3205 ///
3206 /// ```
3207 /// use double_map::DHashMap;
3208 /// use double_map::dhash_map::Entry;
3209 ///
3210 /// let mut map: DHashMap<&str, u32, i32> = DHashMap::new();
3211 /// map.insert("poneyland", 0, 12);
3212 ///
3213 /// if let Ok(entry) = map.entry("poneyland", 0) {
3214 /// match entry {
3215 /// Entry::Occupied(oc_entry) => {
3216 /// assert_eq!(oc_entry.keys(), (&"poneyland", &0));
3217 /// }
3218 /// Entry::Vacant(_) => panic!("Something go wrong!!!")
3219 /// }
3220 /// }
3221 /// ```
3222 #[inline]
3223 pub fn keys(&self) -> (&K1, &K2) {
3224 (self.base_v.key(), self.base_k.key())
3225 }
3226
3227 /// Take the ownership of the keys and value from the map.
3228 /// Keeps the allocated memory for reuse.
3229 ///
3230 /// # Examples
3231 ///
3232 /// ```
3233 /// use double_map::DHashMap;
3234 /// use double_map::dhash_map::Entry;
3235 ///
3236 /// // So lets create some map and insert some element
3237 /// let mut map: DHashMap<&str, u32, i32> = DHashMap::new();
3238 /// map.insert("poneyland", 0, 10);
3239 /// map.insert("bearland", 1, 11);
3240 ///
3241 /// // And also reserve some space for additional elements
3242 /// map.reserve(15);
3243 /// // Now our map can hold at least 17 elements
3244 /// let capacity_before_entries_remove = map.capacity();
3245 /// assert!(capacity_before_entries_remove >= 17);
3246 ///
3247 /// assert!(map.get_key1("poneyland") == Some(&10) && map.get_key2(&0) == Some(&10));
3248 /// if let Ok(entry) = map.entry("poneyland", 0) {
3249 /// match entry {
3250 /// Entry::Occupied(oc_entry) => {
3251 /// // We delete the entry from the map.
3252 /// let tuple = oc_entry.remove_entry();
3253 /// assert_eq!(tuple, ("poneyland", 0, 10));
3254 /// }
3255 /// Entry::Vacant(_) => panic!("Something go wrong!!!")
3256 /// }
3257 /// }
3258 /// assert!(map.get_key1("poneyland") == None && map.get_key2(&0) == None);
3259 ///
3260 /// assert!(map.get_key1("bearland") == Some(&11) && map.get_key2(&1) == Some(&11));
3261 /// if let Ok(entry) = map.entry("bearland", 1) {
3262 /// match entry {
3263 /// Entry::Occupied(oc_entry) => {
3264 /// // We delete the entry from the map.
3265 /// let tuple = oc_entry.remove_entry();
3266 /// assert_eq!(tuple, ("bearland", 1, 11));
3267 /// }
3268 /// Entry::Vacant(_) => panic!("Something go wrong!!!")
3269 /// }
3270 /// }
3271 /// assert!(map.get_key1("bearland") == None && map.get_key2(&1) == None);
3272 ///
3273 /// // But the capacity of our map isn't changed and still equals to the capacity before
3274 /// // using `remove_entry` method
3275 /// assert_eq!(map.capacity(), capacity_before_entries_remove);
3276 /// ```
3277 #[inline]
3278 pub fn remove_entry(self) -> (K1, K2, V) {
3279 self.base_k.remove_entry();
3280 let (k1, (k2, v)) = self.base_v.remove_entry();
3281 (k1, k2, v)
3282 }
3283
3284 /// Gets a reference to the value in the entry.
3285 ///
3286 /// # Examples
3287 ///
3288 /// ```
3289 /// use double_map::DHashMap;
3290 /// use double_map::dhash_map::Entry;
3291 ///
3292 /// let mut map: DHashMap<&str, u32, i32> = DHashMap::new();
3293 /// map.insert("poneyland", 0, 12);
3294 ///
3295 /// if let Ok(entry) = map.entry("poneyland", 0) {
3296 /// match entry {
3297 /// Entry::Occupied(oc_entry) => {
3298 /// assert_eq!(oc_entry.get(), &12);
3299 /// }
3300 /// Entry::Vacant(_) => panic!("Something go wrong!!!")
3301 /// }
3302 /// }
3303 /// ```
3304 #[inline]
3305 pub fn get(&self) -> &V {
3306 let (_, v) = self.base_v.get();
3307 v
3308 }
3309
3310 /// Gets a mutable reference to the value in the entry.
3311 ///
3312 /// If you need a reference to the `OccupiedEntry` which may outlive the
3313 /// destruction of the `Entry` value, see [`into_mut`](`OccupiedEntry::into_mut`).
3314 ///
3315 /// # Examples
3316 ///
3317 /// ```
3318 /// use double_map::DHashMap;
3319 /// use double_map::dhash_map::Entry;
3320 ///
3321 /// let mut map: DHashMap<&str, u32, i32> = DHashMap::new();
3322 /// map.insert("poneyland", 0, 12);
3323 /// assert_eq!(map.get_key1("poneyland"), Some(&12));
3324 /// assert_eq!(map.get_key2(&0), Some(&12));
3325 ///
3326 /// if let Ok(entry) = map.entry("poneyland", 0) {
3327 /// match entry {
3328 /// Entry::Occupied(mut oc_entry) => {
3329 /// *oc_entry.get_mut() += 10;
3330 /// assert_eq!(oc_entry.get(), &22);
3331 ///
3332 /// // We can use the same Entry multiple times.
3333 /// *oc_entry.get_mut() += 2;
3334 /// }
3335 /// Entry::Vacant(_) => panic!("Something go wrong!!!")
3336 /// }
3337 /// }
3338 /// assert_eq!(map.get_key1("poneyland"), Some(&24));
3339 /// assert_eq!(map.get_key2(&0), Some(&24));
3340 /// ```
3341 #[inline]
3342 pub fn get_mut(&mut self) -> &mut V {
3343 let (_, v) = self.base_v.get_mut();
3344 v
3345 }
3346
3347 /// Converts the `OccupiedEntry` into a mutable reference to the value in the entry
3348 /// with a lifetime bound to the map itself.
3349 ///
3350 /// # Examples
3351 ///
3352 /// ```
3353 /// use double_map::DHashMap;
3354 /// use double_map::dhash_map::Entry;
3355 ///
3356 /// let mut map: DHashMap<&str, u32, i32> = DHashMap::new();
3357 /// map.insert("poneyland", 0, 12);
3358 /// assert_eq!(map.get_key1("poneyland"), Some(&12));
3359 /// assert_eq!(map.get_key2(&0), Some(&12));
3360 ///
3361 /// // Let's create a variable that outlives the OccupiedEntry (with some initial value)
3362 /// let mut value: &mut i32 = &mut 0;
3363 ///
3364 /// if let Ok(entry) = map.entry("poneyland", 0) {
3365 /// match entry {
3366 /// Entry::Occupied(oc_entry) => {
3367 /// // So we can convert the OccupiedEntry into a mutable reference to the value.
3368 /// value = oc_entry.into_mut();
3369 /// *value += 10;
3370 /// }
3371 /// Entry::Vacant(_) => panic!("Something go wrong!!!")
3372 /// }
3373 /// }
3374 /// // We can use the same reference outside the created oc_entry (OccupiedEntry) scope.
3375 /// *value += 20;
3376 /// assert_eq!(map.get_key1("poneyland"), Some(&42)); // 12 + 10 + 20
3377 /// assert_eq!(map.get_key2(&0), Some(&42));
3378 /// ```
3379 #[inline]
3380 pub fn into_mut(self) -> &'a mut V {
3381 let (_, v) = self.base_v.into_mut();
3382 v
3383 }
3384
3385 /// Sets the value of the entry, and returns the entry's old value.
3386 ///
3387 /// # Examples
3388 ///
3389 /// ```
3390 /// use double_map::DHashMap;
3391 /// use double_map::dhash_map::Entry;
3392 ///
3393 /// let mut map: DHashMap<&str, u32, i32> = DHashMap::new();
3394 /// map.insert("poneyland", 0, 12);
3395 /// assert_eq!(map.get_key1("poneyland"), Some(&12));
3396 /// assert_eq!(map.get_key2(&0), Some(&12));
3397 ///
3398 /// // Let's create a variable that holds value
3399 /// let mut owner: i32 = 100;
3400 ///
3401 /// if let Ok(entry) = map.entry("poneyland", 0) {
3402 /// match entry {
3403 /// Entry::Occupied(mut oc_entry) => {
3404 /// // So we can swap our created owner value with value inside the map.
3405 /// owner = oc_entry.insert(owner);
3406 /// }
3407 /// Entry::Vacant(_) => panic!("Something go wrong!!!")
3408 /// }
3409 /// }
3410 /// assert_eq!(owner, 12);
3411 /// assert_eq!(map.get_key1("poneyland"), Some(&100));
3412 /// assert_eq!(map.get_key2(&0), Some(&100));
3413 /// ```
3414 #[inline]
3415 pub fn insert(&mut self, mut value: V) -> V {
3416 let old_value = self.get_mut();
3417 mem::swap(&mut value, old_value);
3418 value
3419 }
3420
3421 /// Take the value out of the entry (map), and return it.
3422 /// Keeps the allocated memory for reuse.
3423 ///
3424 /// # Examples
3425 ///
3426 /// ```
3427 /// use double_map::DHashMap;
3428 /// use double_map::dhash_map::Entry;
3429 ///
3430 /// // So lets create some map and insert some element
3431 /// let mut map: DHashMap<&str, u32, i32> = DHashMap::new();
3432 /// map.insert("poneyland", 0, 10);
3433 /// map.insert("bearland", 1, 11);
3434 ///
3435 /// // And also reserve some space for additional elements
3436 /// map.reserve(15);
3437 /// // Now our map can hold at least 17 elements
3438 /// let capacity_before_remove = map.capacity();
3439 /// assert!(capacity_before_remove >= 17);
3440 ///
3441 /// assert!(map.get_key1("poneyland") == Some(&10) && map.get_key2(&0) == Some(&10));
3442 /// if let Ok(entry) = map.entry("poneyland", 0) {
3443 /// match entry {
3444 /// Entry::Occupied(oc_entry) => {
3445 /// // We delete the entry from the map.
3446 /// let value = oc_entry.remove();
3447 /// assert_eq!(value, 10);
3448 /// }
3449 /// Entry::Vacant(_) => panic!("Something go wrong!!!")
3450 /// }
3451 /// }
3452 /// assert!(map.get_key1("poneyland") == None && map.get_key2(&0) == None);
3453 ///
3454 /// assert!(map.get_key1("bearland") == Some(&11) && map.get_key2(&1) == Some(&11));
3455 /// if let Ok(entry) = map.entry("bearland", 1) {
3456 /// match entry {
3457 /// Entry::Occupied(oc_entry) => {
3458 /// // We delete the entry from the map.
3459 /// let value = oc_entry.remove();
3460 /// assert_eq!(value, 11);
3461 /// }
3462 /// Entry::Vacant(_) => panic!("Something go wrong!!!")
3463 /// }
3464 /// }
3465 /// assert!(map.get_key1("bearland") == None && map.get_key2(&1) == None);
3466 ///
3467 /// // But the capacity of our map isn't changed and still equals to the capacity before
3468 /// // using `remove_entry` method
3469 /// assert_eq!(map.capacity(), capacity_before_remove);
3470 /// ```
3471 #[inline]
3472 pub fn remove(self) -> V {
3473 self.remove_entry().2
3474 }
3475}
3476
3477/// A view into a vacant entry in a [`DHashMap`].
3478/// It is part of the [`Entry`] enum.
3479#[derive(Debug)]
3480pub struct VacantEntry<'a, K1: 'a, K2: 'a, V: 'a> {
3481 base_v: hash_map::VacantEntry<'a, K1, (K2, V)>,
3482 base_k: hash_map::VacantEntry<'a, K2, K1>,
3483}
3484
3485impl<'a, K1: 'a, K2: 'a, V: 'a> VacantEntry<'a, K1, K2, V> {
3486 /// Gets a reference to the key #1 of type `K1` that would be used
3487 /// when inserting a value through the `VacantEntry`.
3488 ///
3489 /// # Examples
3490 ///
3491 /// ```
3492 /// use double_map::DHashMap;
3493 /// use double_map::dhash_map::Entry;
3494 ///
3495 /// let mut map: DHashMap<&str, u32, i32> = DHashMap::new();
3496 ///
3497 /// if let Ok(entry) = map.entry("poneyland", 0) {
3498 /// match entry {
3499 /// Entry::Occupied(_) => panic!("Something go wrong!!!"),
3500 /// Entry::Vacant(vac_entry) => assert_eq!(vac_entry.key1(), &"poneyland"),
3501 /// }
3502 /// }
3503 /// ```
3504 #[inline]
3505 pub fn key1(&self) -> &K1 {
3506 self.base_v.key()
3507 }
3508
3509 /// Gets a reference to the key #2 of type `K2` that would be used
3510 /// when inserting a value through the `VacantEntry`.
3511 ///
3512 /// # Examples
3513 ///
3514 /// ```
3515 /// use double_map::DHashMap;
3516 /// use double_map::dhash_map::Entry;
3517 ///
3518 /// let mut map: DHashMap<&str, u32, i32> = DHashMap::new();
3519 ///
3520 /// if let Ok(entry) = map.entry("poneyland", 0) {
3521 /// match entry {
3522 /// Entry::Occupied(_) => panic!("Something go wrong!!!"),
3523 /// Entry::Vacant(vac_entry) => assert_eq!(vac_entry.key2(), &0),
3524 /// }
3525 /// }
3526 /// ```
3527 #[inline]
3528 pub fn key2(&self) -> &K2 {
3529 self.base_k.key()
3530 }
3531
3532 /// Gets a reference to the keys of type `K1` and `K2` that would be used
3533 /// when inserting a value through the `VacantEntry`.
3534 /// Return tuple of type `(&'a K1, &'a K2)`.
3535 ///
3536 /// # Examples
3537 ///
3538 /// ```
3539 /// use double_map::DHashMap;
3540 /// use double_map::dhash_map::Entry;
3541 ///
3542 /// let mut map: DHashMap<&str, u32, i32> = DHashMap::new();
3543 ///
3544 /// if let Ok(entry) = map.entry("poneyland", 0) {
3545 /// match entry {
3546 /// Entry::Occupied(_) => panic!("Something go wrong!!!"),
3547 /// Entry::Vacant(vac_entry) => {
3548 /// assert_eq!(vac_entry.keys(), (&"poneyland", &0))
3549 /// }
3550 /// }
3551 /// }
3552 /// ```
3553 #[inline]
3554 pub fn keys(&self) -> (&K1, &K2) {
3555 (self.base_v.key(), self.base_k.key())
3556 }
3557
3558 /// Take the ownership of the keys from the entry.
3559 ///
3560 /// # Examples
3561 ///
3562 /// ```
3563 /// use double_map::DHashMap;
3564 /// use double_map::dhash_map::Entry;
3565 ///
3566 /// // So lets create some map and also reserve some space for additional elements
3567 /// let mut map: DHashMap<&str, u32, i32> = DHashMap::with_capacity(3);
3568 ///
3569 /// let capacity_before_into_keys = map.capacity();
3570 /// assert!(capacity_before_into_keys >= 3);
3571 ///
3572 /// if let Ok(entry) = map.entry("poneyland", 0) {
3573 /// match entry {
3574 /// Entry::Occupied(_) => panic!("Something go wrong!!!"),
3575 /// Entry::Vacant(vac_entry) => {
3576 /// // We take the keys from the entry.
3577 /// let tuple = vac_entry.into_keys();
3578 /// assert_eq!(tuple, ("poneyland", 0));
3579 /// }
3580 /// }
3581 /// }
3582 ///
3583 /// if let Ok(entry) = map.entry("bearland", 1) {
3584 /// match entry {
3585 /// Entry::Occupied(_) => panic!("Something go wrong!!!"),
3586 /// Entry::Vacant(vac_entry) => {
3587 /// // We take the keys from the entry.
3588 /// let tuple = vac_entry.into_keys();
3589 /// assert_eq!(tuple, ("bearland", 1));
3590 /// }
3591 /// }
3592 /// }
3593 ///
3594 /// map.entry("some_key", 2);
3595 /// map.entry("another_key", 3);
3596 ///
3597 /// // The capacity of our map is not changed
3598 /// assert_eq!(map.capacity(), capacity_before_into_keys);
3599 /// ```
3600 #[inline]
3601 pub fn into_keys(self) -> (K1, K2) {
3602 (self.base_v.into_key(), self.base_k.into_key())
3603 }
3604}
3605
3606impl<'a, K1: 'a + Clone, K2: 'a + Clone, V: 'a> VacantEntry<'a, K1, K2, V> {
3607 /// Sets the value of the entry with the `VacantEntry`'s keys,
3608 /// and returns a mutable reference to it.
3609 ///
3610 /// # Examples
3611 ///
3612 /// ```
3613 /// use double_map::DHashMap;
3614 /// use double_map::dhash_map::Entry;
3615 ///
3616 /// // So lets create some map
3617 /// let mut map: DHashMap<&str, u32, i32> = DHashMap::new();
3618 ///
3619 /// if let Ok(entry) = map.entry("poneyland", 0) {
3620 /// match entry {
3621 /// Entry::Occupied(_) => panic!("Something go wrong!!!"),
3622 /// Entry::Vacant(vac_entry) => {
3623 /// vac_entry.insert(37);
3624 /// }
3625 /// }
3626 /// }
3627 /// assert_eq!(map.get_key1(&"poneyland"), Some(&37));
3628 /// ```
3629 #[inline]
3630 pub fn insert(self, value: V) -> &'a mut V {
3631 let k2 = self.base_k.key().clone();
3632 self.base_k.insert(self.base_v.key().clone());
3633 let (_, v) = self.base_v.insert((k2, value));
3634 v
3635 }
3636}
3637
3638/// A view into a single entry in a map, which may either be vacant or occupied.
3639///
3640/// This `enum` is constructed from the [`entry`] method on [`DHashMap`].
3641///
3642/// [`entry`]: DHashMap::entry
3643#[derive(Debug)]
3644pub enum Entry<'a, K1: 'a, K2: 'a, V: 'a> {
3645 /// An occupied entry.
3646 Occupied(OccupiedEntry<'a, K1, K2, V>),
3647 /// A vacant entry.
3648 Vacant(VacantEntry<'a, K1, K2, V>),
3649}
3650
3651impl<'a, K1: Clone, K2: Clone, V> Entry<'a, K1, K2, V> {
3652 /// Ensures a value is in the entry by inserting the default if empty, and returns
3653 /// a mutable reference to the value in the entry.
3654 ///
3655 /// # Examples
3656 ///
3657 /// ```
3658 /// use double_map::DHashMap;
3659 ///
3660 /// let mut map: DHashMap<&str, u32, i32> = DHashMap::new();
3661 ///
3662 /// match map.entry("poneyland", 0) {
3663 /// Ok(entry) => {
3664 /// entry.or_insert(3);
3665 /// }
3666 /// Err(_) => unreachable!(),
3667 /// }
3668 /// assert_eq!(map.get_key1(&"poneyland"), Some(&3));
3669 ///
3670 /// map.entry("poneyland", 0).map(|entry| *entry.or_insert(10) *= 2);
3671 /// assert_eq!(map.get_key1(&"poneyland"), Some(&6));
3672 /// ```
3673 #[inline]
3674 pub fn or_insert(self, default: V) -> &'a mut V {
3675 match self {
3676 Entry::Occupied(entry) => entry.into_mut(),
3677 Entry::Vacant(entry) => entry.insert(default),
3678 }
3679 }
3680
3681 /// Ensures a value is in the entry by inserting the result of the default function if empty,
3682 /// and returns a mutable reference to the value in the entry.
3683 ///
3684 /// # Examples
3685 ///
3686 /// ```
3687 /// use double_map::DHashMap;
3688 ///
3689 /// let mut map: DHashMap<&str, u32, String> = DHashMap::new();
3690 /// let s = "hoho".to_owned();
3691 ///
3692 /// match map.entry("poneyland", 0) {
3693 /// Ok(entry) => {
3694 /// entry.or_insert_with(|| s);
3695 /// }
3696 /// Err(_) => unreachable!(),
3697 /// }
3698 /// assert_eq!(map.get_key1("poneyland"), Some(&"hoho".to_owned()));
3699 ///
3700 /// let k = "another string".to_owned();
3701 /// map.entry("poneyland", 0).map(|entry| entry.or_insert_with(|| k).push_str("ho"));
3702 /// assert_eq!(map.get_key1(&"poneyland"), Some(&"hohoho".to_owned()));
3703 /// ```
3704 #[inline]
3705 pub fn or_insert_with<F: FnOnce() -> V>(self, default: F) -> &'a mut V {
3706 match self {
3707 Entry::Occupied(entry) => entry.into_mut(),
3708 Entry::Vacant(entry) => entry.insert(default()),
3709 }
3710 }
3711
3712 /// Ensures a value is in the entry by inserting, if empty, the result of the default function.
3713 /// This method allows generating key-derived (with using key # 1 `K1`) value for
3714 /// insertion by providing the default function a reference to the key that was moved
3715 /// during the `.entry(key)` method call.
3716 ///
3717 /// The reference to the moved key is provided so that cloning or copying the key is
3718 /// unnecessary, unlike with `.or_insert_with(|| ... )`.
3719 ///
3720 /// # Examples
3721 ///
3722 /// ```
3723 /// use double_map::DHashMap;
3724 ///
3725 /// let mut map: DHashMap<&str, usize, u64> = DHashMap::new();
3726 ///
3727 /// match map.entry("poneyland", 0) {
3728 /// Ok(entry) => {
3729 /// entry.or_insert_with_key1(|k1| k1.chars().count() as u64);
3730 /// },
3731 /// Err(_) => unreachable!(),
3732 /// }
3733 /// assert_eq!(map.get_key1(&"poneyland"), Some(&9));
3734 ///
3735 /// map.entry("bearland", 1).map(
3736 /// |ent| ent.or_insert_with_key1(|k1| (k1.chars().count() * 2) as u64)
3737 /// );
3738 /// assert_eq!(map.get_key1(&"bearland"), Some(&16));
3739 /// ```
3740 #[inline]
3741 pub fn or_insert_with_key1<F: FnOnce(&K1) -> V>(self, default: F) -> &'a mut V {
3742 match self {
3743 Entry::Occupied(entry) => entry.into_mut(),
3744 Entry::Vacant(entry) => {
3745 let value = default(entry.key1());
3746 entry.insert(value)
3747 }
3748 }
3749 }
3750
3751 /// Ensures a value is in the entry by inserting, if empty, the result of the default function.
3752 /// This method allows generating key-derived (with using key # 2 `K2`) value for
3753 /// insertion by providing the default function a reference to the key that was moved
3754 /// during the `.entry(key)` method call.
3755 ///
3756 /// The reference to the moved key is provided so that cloning or copying the key is
3757 /// unnecessary, unlike with `.or_insert_with(|| ... )`.
3758 ///
3759 /// # Examples
3760 ///
3761 /// ```
3762 /// use double_map::DHashMap;
3763 ///
3764 /// let mut map: DHashMap<&str, usize, u64> = DHashMap::new();
3765 ///
3766 /// match map.entry("poneyland", 10) {
3767 /// Ok(entry) => {
3768 /// entry.or_insert_with_key2(|k2| (k2 + 10) as u64);
3769 /// },
3770 /// Err(_) => unreachable!(),
3771 /// }
3772 /// assert_eq!(map.get_key1(&"poneyland"), Some(&20));
3773 ///
3774 /// map.entry("bearland", 11).map(
3775 /// |ent| ent.or_insert_with_key2(|k1| (k1 * 3) as u64)
3776 /// );
3777 /// assert_eq!(map.get_key1(&"bearland"), Some(&33));
3778 /// ```
3779 #[inline]
3780 pub fn or_insert_with_key2<F: FnOnce(&K2) -> V>(self, default: F) -> &'a mut V {
3781 match self {
3782 Entry::Occupied(entry) => entry.into_mut(),
3783 Entry::Vacant(entry) => {
3784 let value = default(entry.key2());
3785 entry.insert(value)
3786 }
3787 }
3788 }
3789
3790 /// Ensures a value is in the entry by inserting, if empty, the result of the default function.
3791 /// This method allows generating key-derived (with using key #1 of type `K1` and
3792 /// key # 2 of type `K2`) values for insertion by providing the default function
3793 /// a reference to the keys that were moved during the `.entry(key)` method call.
3794 ///
3795 /// The reference to the moved keys is provided so that cloning or copying the key is
3796 /// unnecessary, unlike with `.or_insert_with(|| ... )`.
3797 ///
3798 /// # Examples
3799 ///
3800 /// ```
3801 /// use double_map::DHashMap;
3802 ///
3803 /// let mut map: DHashMap<&str, usize, u64> = DHashMap::new();
3804 ///
3805 /// match map.entry("poneyland", 10) {
3806 /// Ok(entry) => {
3807 /// entry.or_insert_with_keys(|k1, k2| (k1.chars().count() + k2) as u64);
3808 /// },
3809 /// Err(_) => unreachable!(),
3810 /// }
3811 /// assert_eq!(map.get_key1(&"poneyland"), Some(&19));
3812 ///
3813 /// map.entry("bearland", 11).map(
3814 /// |ent| ent.or_insert_with_keys(|k1, k2| (k1.chars().count() + k2 * 3) as u64)
3815 /// );
3816 /// assert_eq!(map.get_key1(&"bearland"), Some(&41));
3817 /// ```
3818 #[inline]
3819 pub fn or_insert_with_keys<F: FnOnce(&K1, &K2) -> V>(self, default: F) -> &'a mut V {
3820 match self {
3821 Entry::Occupied(entry) => entry.into_mut(),
3822 Entry::Vacant(entry) => {
3823 let value = default(entry.key1(), entry.key2());
3824 entry.insert(value)
3825 }
3826 }
3827 }
3828}
3829
3830impl<'a, K1, K2, V> Entry<'a, K1, K2, V> {
3831 /// Returns a reference to this entry's first key (key #1).
3832 ///
3833 /// # Examples
3834 ///
3835 /// ```
3836 /// use double_map::DHashMap;
3837 ///
3838 /// let mut map: DHashMap<&str, u32, i32> = DHashMap::new();
3839 ///
3840 /// // It is VacantEntry
3841 /// match map.entry("poneyland", 0) {
3842 /// Ok(entry) => {
3843 /// // key equal to provided one
3844 /// assert_eq!(entry.key1(), &"poneyland");
3845 /// // we insert some value
3846 /// entry.or_insert(25);
3847 /// },
3848 /// Err(_) => unreachable!(),
3849 /// }
3850 /// // As we can see, now this element exists
3851 /// assert_eq!(map.get_key1(&"poneyland"), Some(&25));
3852 ///
3853 /// // So now it is OccupiedEntry
3854 /// match map.entry("poneyland", 0) {
3855 /// Ok(entry) => {
3856 /// // And key equals to provided one too
3857 /// assert_eq!(entry.key1(), &"poneyland");
3858 /// entry.or_insert(25);
3859 /// },
3860 /// Err(_) => unreachable!(),
3861 /// }
3862 /// ```
3863 #[inline]
3864 pub fn key1(&self) -> &K1 {
3865 match *self {
3866 Entry::Occupied(ref entry) => entry.key1(),
3867 Entry::Vacant(ref entry) => entry.key1(),
3868 }
3869 }
3870
3871 /// Returns a reference to this entry's second key (key #2).
3872 ///
3873 /// # Examples
3874 ///
3875 /// ```
3876 /// use double_map::DHashMap;
3877 ///
3878 /// let mut map: DHashMap<&str, u32, i32> = DHashMap::new();
3879 ///
3880 /// // It is VacantEntry
3881 /// match map.entry("poneyland", 10) {
3882 /// Ok(entry) => {
3883 /// // key equal to provided one
3884 /// assert_eq!(entry.key2(), &10);
3885 /// // we insert some value
3886 /// entry.or_insert(25);
3887 /// },
3888 /// Err(_) => unreachable!(),
3889 /// }
3890 /// // As we can see, now this element exists
3891 /// assert_eq!(map.get_key2(&10), Some(&25));
3892 ///
3893 /// // So now it is OccupiedEntry
3894 /// match map.entry("poneyland", 10) {
3895 /// Ok(entry) => {
3896 /// // And key equals to provided one too
3897 /// assert_eq!(entry.key2(), &10);
3898 /// entry.or_insert(25);
3899 /// },
3900 /// Err(_) => unreachable!(),
3901 /// }
3902 /// ```
3903 #[inline]
3904 pub fn key2(&self) -> &K2 {
3905 match *self {
3906 Entry::Occupied(ref entry) => entry.key2(),
3907 Entry::Vacant(ref entry) => entry.key2(),
3908 }
3909 }
3910
3911 /// Returns a reference to this entry's keys.
3912 /// Return tuple of type (&'a K1, &'a K2).
3913 ///
3914 /// # Examples
3915 ///
3916 /// ```
3917 /// use double_map::DHashMap;
3918 ///
3919 /// let mut map: DHashMap<&str, u32, i32> = DHashMap::new();
3920 ///
3921 /// // It is VacantEntry
3922 /// match map.entry("poneyland", 10) {
3923 /// Ok(entry) => {
3924 /// // keys equal to provided one
3925 /// assert_eq!(entry.keys(), (&"poneyland", &10));
3926 /// // we insert some value
3927 /// entry.or_insert(25);
3928 /// },
3929 /// Err(_) => unreachable!(),
3930 /// }
3931 /// // As we can see, now this element exists
3932 /// assert_eq!(map.get_key1(&"poneyland"), Some(&25));
3933 ///
3934 /// // So now it is OccupiedEntry
3935 /// match map.entry("poneyland", 10) {
3936 /// Ok(entry) => {
3937 /// // And keys equal to provided one too
3938 /// assert_eq!(entry.keys(), (&"poneyland", &10));
3939 /// entry.or_insert(25);
3940 /// },
3941 /// Err(_) => unreachable!(),
3942 /// }
3943 /// ```
3944 #[inline]
3945 pub fn keys(&self) -> (&K1, &K2) {
3946 match *self {
3947 Entry::Occupied(ref entry) => entry.keys(),
3948 Entry::Vacant(ref entry) => entry.keys(),
3949 }
3950 }
3951
3952 /// Provides in-place mutable access to an occupied entry before any
3953 /// potential inserts into the map.
3954 ///
3955 /// # Examples
3956 ///
3957 /// ```
3958 /// use double_map::DHashMap;
3959 ///
3960 /// let mut map: DHashMap<&str, u32, u32> = DHashMap::new();
3961 ///
3962 /// map.entry("poneyland", 1).map( |entry|
3963 /// entry.and_modify(|value| { *value += 100 })
3964 /// .or_insert(42)
3965 /// );
3966 /// assert_eq!(map.get_key1(&"poneyland"), Some(&42));
3967 ///
3968 /// map.entry("poneyland", 1).map( |entry|
3969 /// entry.and_modify(|value| { *value += 100 })
3970 /// .or_insert(42)
3971 /// );
3972 /// assert_eq!(map.get_key1(&"poneyland"), Some(&142));
3973 /// ```
3974 #[inline]
3975 pub fn and_modify<F>(self, f: F) -> Self
3976 where
3977 F: FnOnce(&mut V),
3978 {
3979 match self {
3980 Entry::Occupied(mut entry) => {
3981 f(entry.get_mut());
3982 Entry::Occupied(entry)
3983 }
3984 Entry::Vacant(entry) => Entry::Vacant(entry),
3985 }
3986 }
3987}
3988
3989impl<'a, K1: Clone, K2: Clone, V: Default> Entry<'a, K1, K2, V> {
3990 /// Ensures a value is in the entry by inserting the default value if empty,
3991 /// and returns a mutable reference to the value in the entry.
3992 ///
3993 /// # Examples
3994 ///
3995 /// ```
3996 /// # fn main() {
3997 /// use double_map::DHashMap;
3998 ///
3999 /// let mut map: DHashMap<&str, usize, Option<u32>> = DHashMap::new();
4000 /// map.entry("poneyland", 1).map(|entry| entry.or_default());
4001 ///
4002 /// assert_eq!(map.get_key1(&"poneyland"), Option::<&Option<u32>>::Some(&None));
4003 /// # }
4004 /// ```
4005 #[inline]
4006 pub fn or_default(self) -> &'a mut V {
4007 match self {
4008 Entry::Occupied(entry) => entry.into_mut(),
4009 Entry::Vacant(entry) => entry.insert(Default::default()),
4010 }
4011 }
4012}
4013
4014/// A view into an error kind returned by [`entry`](DHashMap::entry), [`insert`](DHashMap::insert),
4015/// [`try_insert`](DHashMap::try_insert) methods of the [`DHashMap`].
4016/// It is part of the [`EntryError`] structure, [`InsertError`] structure and [`TryInsertError`]
4017/// enum.
4018///
4019/// Explains why [`entry`](DHashMap::entry), [`insert`](DHashMap::insert),
4020/// [`try_insert`](DHashMap::try_insert) methods fail.
4021#[derive(Copy, Clone, Debug, PartialEq, Eq)]
4022pub enum ErrorKind {
4023 /// Returns when key #1 is vacant, but key #2 already exists with some value.
4024 VacantK1AndOccupiedK2,
4025 /// Returns when key #1 already exists with some value, but key #2 is vacant.
4026 OccupiedK1AndVacantK2,
4027 /// Returns when both key #1 and key #2 already exist with some values, but point
4028 /// to different entries (values).
4029 KeysPointsToDiffEntries,
4030}
4031
4032impl fmt::Display for ErrorKind {
4033 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4034 let error_txt = match *self {
4035 ErrorKind::OccupiedK1AndVacantK2 => "occupied key #1 but vacant key #2",
4036 ErrorKind::VacantK1AndOccupiedK2 => "vacant key #1 but occupied key #2",
4037 ErrorKind::KeysPointsToDiffEntries => {
4038 "key #1 and key #2 exist, but point to different entries"
4039 }
4040 };
4041 write!(f, "{}", error_txt)
4042 }
4043}
4044
4045impl std::error::Error for ErrorKind {}
4046
4047/// The error returned by [`entry`](DHashMap::entry) method when there is no way to distinguish
4048/// which entry should be returned. For more information about error kinds look at [`ErrorKind`]
4049/// enum.
4050///
4051/// Contains the [`ErrorKind`] enum, and the values of provided keys (that can be used for another
4052/// purpose).
4053#[derive(Debug, PartialEq)]
4054pub struct EntryError<K1, K2> {
4055 /// A view into an error kind returned by [`entry`](DHashMap::entry),
4056 /// [`insert`](DHashMap::insert), [`try_insert`](DHashMap::try_insert) methods of the [`DHashMap`].
4057 /// It is part of the [`EntryError`] structure, [`InsertError`] structure and [`TryInsertError`]
4058 /// enum. Explains [`entry`](DHashMap::entry), [`insert`](DHashMap::insert),
4059 /// [`try_insert`](DHashMap::try_insert) methods fail. For more information about error
4060 /// kind look at [`ErrorKind`] enum.
4061 pub error: ErrorKind,
4062 /// The provided values of keys that were returned because of error. For more information about
4063 /// error kind look at [`ErrorKind`] enum.
4064 pub keys: (K1, K2),
4065}
4066
4067impl<K1: Debug, K2: Debug> fmt::Display for EntryError<K1, K2> {
4068 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4069 let key_txt = match self.error {
4070 ErrorKind::VacantK1AndOccupiedK2 => format!(
4071 "key #1 = {:?} - vacant, but key #2 = {:?} - exists",
4072 self.keys.0, self.keys.1
4073 ),
4074 ErrorKind::OccupiedK1AndVacantK2 => format!(
4075 "key #1 = {:?} - exists, but key #2 = {:?} - vacant",
4076 self.keys.0, self.keys.1
4077 ),
4078 ErrorKind::KeysPointsToDiffEntries => format!(
4079 "key #1 = {:?} and key #2 = {:?} point to different entries",
4080 self.keys.0, self.keys.1
4081 ),
4082 };
4083 write!(f, "failed to get entry, because {}", key_txt)
4084 }
4085}
4086
4087impl<K1: Debug, K2: Debug> std::error::Error for EntryError<K1, K2> {}
4088
4089/// The error returned by [`insert`](DHashMap::insert) method (and also
4090/// [`try_insert`](DHashMap::try_insert) method) when there is no way to distinguish
4091/// how given value with key #1 and key #2 should be inserted. It is also part of the
4092/// [`TryInsertError`] enum which is returned by [`try_insert`](DHashMap::try_insert) method
4093/// of [`DHashMap`]. For more information about error kinds look at [`ErrorKind`] enum.
4094///
4095/// Contains the [`ErrorKind`] enum, the provided keys and value that were not inserted.
4096/// These returned keys and value can be used for another purpose.
4097#[derive(Debug, PartialEq)]
4098pub struct InsertError<K1, K2, V> {
4099 /// A view into an error kind returned by [`entry`](DHashMap::entry),
4100 /// [`insert`](DHashMap::insert), [`try_insert`](DHashMap::try_insert) methods of the [`DHashMap`].
4101 /// It is part of the [`EntryError`] structure, [`InsertError`] structure and [`TryInsertError`]
4102 /// enum. Explains [`entry`](DHashMap::entry), [`insert`](DHashMap::insert),
4103 /// [`try_insert`](DHashMap::try_insert) methods fail. For more information about error
4104 /// kind look at [`ErrorKind`] enum.
4105 pub error: ErrorKind,
4106 /// The provided keys that were returned because of error. For more information about
4107 /// error kind look at [`ErrorKind`] enum.
4108 pub keys: (K1, K2),
4109 /// The value which was not inserted because of the error. For more information about error
4110 /// kind look at [`ErrorKind`] enum.
4111 pub value: V,
4112}
4113
4114impl<K1: Debug, K2: Debug, V: Debug> fmt::Display for InsertError<K1, K2, V> {
4115 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4116 let key_txt = match self.error {
4117 ErrorKind::VacantK1AndOccupiedK2 => format!(
4118 "key #1 = {:?} - vacant, but key #2 = {:?} - exists",
4119 self.keys.0, self.keys.1
4120 ),
4121 ErrorKind::OccupiedK1AndVacantK2 => format!(
4122 "key #1 = {:?} - exists, but key #2 = {:?} - vacant",
4123 self.keys.0, self.keys.1
4124 ),
4125 ErrorKind::KeysPointsToDiffEntries => format!(
4126 "key #1 = {:?} and key #2 = {:?} point to different entries",
4127 self.keys.0, self.keys.1
4128 ),
4129 };
4130 write!(
4131 f,
4132 "failed to insert {:?}, because of {}",
4133 self.value, key_txt
4134 )
4135 }
4136}
4137
4138impl<K1: Debug, K2: Debug, V: Debug> std::error::Error for InsertError<K1, K2, V> {}
4139
4140/// The error returned by [`try_insert`](DHashMap::try_insert) (as a part of the [`TryInsertError`]
4141/// enum) when the keys already exist and point to the same value.
4142///
4143/// Contains the occupied entry, and the value that was not inserted. It is part of the
4144/// [`TryInsertError`] enum.
4145#[derive(Debug)]
4146pub struct OccupiedError<'a, K1: 'a, K2: 'a, V: 'a> {
4147 /// The entry in the map that was already occupied. It contains [`OccupiedEntry`] structure
4148 /// which is also a part of the [`Entry`] enum.
4149 pub entry: OccupiedEntry<'a, K1, K2, V>,
4150 /// The value which was not inserted, because the entry was already occupied.
4151 pub value: V,
4152}
4153
4154impl<'a, K1: Debug, K2: Debug, V: Debug> fmt::Display for OccupiedError<'a, K1, K2, V> {
4155 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4156 write!(
4157 f,
4158 "failed to insert {:?}, key #1 = {:?} and key #2 = {:?} already exist with value {:?}",
4159 self.value,
4160 self.entry.key1(),
4161 self.entry.key2(),
4162 self.entry.get(),
4163 )
4164 }
4165}
4166
4167impl<'a, K1: Debug, K2: Debug, V: Debug> std::error::Error for OccupiedError<'a, K1, K2, V> {}
4168
4169/// The error returned by [`try_insert`](DHashMap::try_insert) method when the keys already exist
4170/// and point to the same value (look at [`OccupiedError`]) or there is no way to distinguish how
4171/// given value with key #1 and key #2 should be inserted. For more information about error kinds
4172/// look at [`OccupiedError`], [`InsertError`] structures and [`ErrorKind`] enum.
4173///
4174/// Depending of error kind, this enum can contain:
4175/// - When there is [`TryInsertError::Occupied`] variant, it contains the occupied entry, and
4176/// the value that was not inserted (through [`OccupiedError`] structure).
4177/// - When there is [`TryInsertError::Insert`] variant, it contains the [`ErrorKind`] enum,
4178/// the provided keys and value that were not inserted (through [`InsertError`] structure).
4179#[derive(Debug)]
4180pub enum TryInsertError<'a, K1: 'a, K2: 'a, V: 'a> {
4181 /// The error kind returned by [`try_insert`](DHashMap::try_insert) when the keys already
4182 /// exist and point to the same value. Contains the [`OccupiedError`] structure.
4183 Occupied(OccupiedError<'a, K1, K2, V>),
4184 /// The error kind returned by [`try_insert`](DHashMap::try_insert) method when there is no
4185 /// way to distinguish how given value with key #1 and key #2 should be inserted. For more
4186 /// information about error kinds look at [`InsertError`] structure and [`ErrorKind`] enum.
4187 ///
4188 /// Contains the [`InsertError`] structure.
4189 Insert(InsertError<K1, K2, V>),
4190}
4191
4192impl<'a, K1: Debug, K2: Debug, V: Debug> fmt::Display for TryInsertError<'a, K1, K2, V> {
4193 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4194 let txt = match self {
4195 TryInsertError::Occupied(error) => error.to_string(),
4196 TryInsertError::Insert(error) => error.to_string(),
4197 };
4198 write!(f, "{}", txt)
4199 }
4200}
4201
4202impl<'a, K1: Debug, K2: Debug, V: Debug> std::error::Error for TryInsertError<'a, K1, K2, V> {}