hashbrown/raw_entry.rs
1use crate::Equivalent;
2use crate::alloc::{Allocator, Global};
3use crate::map::{HashMap, equivalent, make_hash, make_hasher};
4use crate::raw::{Bucket, RawTable};
5use core::fmt::{self, Debug};
6use core::hash::{BuildHasher, Hash};
7use core::mem;
8
9impl<K, V, S, A: Allocator> HashMap<K, V, S, A> {
10 /// Creates a raw entry builder for the `HashMap`.
11 ///
12 /// Raw entries provide the lowest level of control for searching and
13 /// manipulating a map. They must be manually initialized with a hash and
14 /// then manually searched. After this, insertions into a vacant entry
15 /// still require an owned key to be provided.
16 ///
17 /// Raw entries are useful for such exotic situations as:
18 ///
19 /// * Hash memoization
20 /// * Deferring the creation of an owned key until it is known to be required
21 /// * Using a search key that doesn't work with the Borrow trait
22 /// * Using custom comparison logic without newtype wrappers
23 ///
24 /// Because raw entries provide much more low-level control, it's much easier
25 /// to put the `HashMap` into an inconsistent state which, while memory-safe,
26 /// will cause the map to produce seemingly random results. Higher-level and
27 /// more foolproof APIs like `entry` should be preferred when possible.
28 ///
29 /// In particular, the hash used to initialized the raw entry must still be
30 /// consistent with the hash of the key that is ultimately stored in the entry.
31 /// This is because implementations of `HashMap` may need to recompute hashes
32 /// when resizing, at which point only the keys are available.
33 ///
34 /// Raw entries give mutable access to the keys. This must not be used
35 /// to modify how the key would compare or hash, as the map will not re-evaluate
36 /// where the key should go, meaning the keys may become "lost" if their
37 /// location does not reflect their state. For instance, if you change a key
38 /// so that the map now contains keys which compare equal, search may start
39 /// acting erratically, with two keys randomly masking each other. Implementations
40 /// are free to assume this doesn't happen (within the limits of memory-safety).
41 ///
42 /// # Examples
43 ///
44 /// ```
45 /// use core::hash::{BuildHasher, Hash};
46 /// use hashbrown::hash_map::{HashMap, RawEntryMut};
47 ///
48 /// let mut map = HashMap::new();
49 /// map.extend([("a", 100), ("b", 200), ("c", 300)]);
50 ///
51 /// fn compute_hash<K: Hash + ?Sized, S: BuildHasher>(hash_builder: &S, key: &K) -> u64 {
52 /// use core::hash::Hasher;
53 /// let mut state = hash_builder.build_hasher();
54 /// key.hash(&mut state);
55 /// state.finish()
56 /// }
57 ///
58 /// // Existing key (insert and update)
59 /// match map.raw_entry_mut().from_key(&"a") {
60 /// RawEntryMut::Vacant(_) => unreachable!(),
61 /// RawEntryMut::Occupied(mut view) => {
62 /// assert_eq!(view.get(), &100);
63 /// let v = view.get_mut();
64 /// let new_v = (*v) * 10;
65 /// *v = new_v;
66 /// assert_eq!(view.insert(1111), 1000);
67 /// }
68 /// }
69 ///
70 /// assert_eq!(map[&"a"], 1111);
71 /// assert_eq!(map.len(), 3);
72 ///
73 /// // Existing key (take)
74 /// let hash = compute_hash(map.hasher(), &"c");
75 /// match map.raw_entry_mut().from_key_hashed_nocheck(hash, &"c") {
76 /// RawEntryMut::Vacant(_) => unreachable!(),
77 /// RawEntryMut::Occupied(view) => {
78 /// assert_eq!(view.remove_entry(), ("c", 300));
79 /// }
80 /// }
81 /// assert_eq!(map.raw_entry().from_key(&"c"), None);
82 /// assert_eq!(map.len(), 2);
83 ///
84 /// // Nonexistent key (insert and update)
85 /// let key = "d";
86 /// let hash = compute_hash(map.hasher(), &key);
87 /// match map.raw_entry_mut().from_hash(hash, |q| *q == key) {
88 /// RawEntryMut::Occupied(_) => unreachable!(),
89 /// RawEntryMut::Vacant(view) => {
90 /// let (k, value) = view.insert("d", 4000);
91 /// assert_eq!((*k, *value), ("d", 4000));
92 /// *value = 40000;
93 /// }
94 /// }
95 /// assert_eq!(map[&"d"], 40000);
96 /// assert_eq!(map.len(), 3);
97 ///
98 /// match map.raw_entry_mut().from_hash(hash, |q| *q == key) {
99 /// RawEntryMut::Vacant(_) => unreachable!(),
100 /// RawEntryMut::Occupied(view) => {
101 /// assert_eq!(view.remove_entry(), ("d", 40000));
102 /// }
103 /// }
104 /// assert_eq!(map.get(&"d"), None);
105 /// assert_eq!(map.len(), 2);
106 /// ```
107 #[cfg_attr(feature = "inline-more", inline)]
108 pub fn raw_entry_mut(&mut self) -> RawEntryBuilderMut<'_, K, V, S, A> {
109 RawEntryBuilderMut { map: self }
110 }
111
112 /// Creates a raw immutable entry builder for the `HashMap`.
113 ///
114 /// Raw entries provide the lowest level of control for searching and
115 /// manipulating a map. They must be manually initialized with a hash and
116 /// then manually searched.
117 ///
118 /// This is useful for
119 /// * Hash memoization
120 /// * Using a search key that doesn't work with the Borrow trait
121 /// * Using custom comparison logic without newtype wrappers
122 ///
123 /// Unless you are in such a situation, higher-level and more foolproof APIs like
124 /// `get` should be preferred.
125 ///
126 /// Immutable raw entries have very limited use; you might instead want `raw_entry_mut`.
127 ///
128 /// # Examples
129 ///
130 /// ```
131 /// use core::hash::{BuildHasher, Hash};
132 /// use hashbrown::HashMap;
133 ///
134 /// let mut map = HashMap::new();
135 /// map.extend([("a", 100), ("b", 200), ("c", 300)]);
136 ///
137 /// fn compute_hash<K: Hash + ?Sized, S: BuildHasher>(hash_builder: &S, key: &K) -> u64 {
138 /// use core::hash::Hasher;
139 /// let mut state = hash_builder.build_hasher();
140 /// key.hash(&mut state);
141 /// state.finish()
142 /// }
143 ///
144 /// for k in ["a", "b", "c", "d", "e", "f"] {
145 /// let hash = compute_hash(map.hasher(), k);
146 /// let v = map.get(&k).cloned();
147 /// let kv = v.as_ref().map(|v| (&k, v));
148 ///
149 /// println!("Key: {} and value: {:?}", k, v);
150 ///
151 /// assert_eq!(map.raw_entry().from_key(&k), kv);
152 /// assert_eq!(map.raw_entry().from_hash(hash, |q| *q == k), kv);
153 /// assert_eq!(map.raw_entry().from_key_hashed_nocheck(hash, &k), kv);
154 /// }
155 /// ```
156 #[cfg_attr(feature = "inline-more", inline)]
157 pub fn raw_entry(&self) -> RawEntryBuilder<'_, K, V, S, A> {
158 RawEntryBuilder { map: self }
159 }
160}
161
162/// A builder for computing where in a [`HashMap`] a key-value pair would be stored.
163///
164/// See the [`HashMap::raw_entry_mut`] docs for usage examples.
165///
166/// [`HashMap::raw_entry_mut`]: HashMap::raw_entry_mut
167///
168/// # Examples
169///
170/// ```
171/// use hashbrown::hash_map::{RawEntryBuilderMut, RawEntryMut::Vacant, RawEntryMut::Occupied};
172/// use hashbrown::HashMap;
173/// use core::hash::{BuildHasher, Hash};
174///
175/// let mut map = HashMap::new();
176/// map.extend([(1, 11), (2, 12), (3, 13), (4, 14), (5, 15), (6, 16)]);
177/// assert_eq!(map.len(), 6);
178///
179/// fn compute_hash<K: Hash + ?Sized, S: BuildHasher>(hash_builder: &S, key: &K) -> u64 {
180/// use core::hash::Hasher;
181/// let mut state = hash_builder.build_hasher();
182/// key.hash(&mut state);
183/// state.finish()
184/// }
185///
186/// let builder: RawEntryBuilderMut<_, _, _> = map.raw_entry_mut();
187///
188/// // Existing key
189/// match builder.from_key(&6) {
190/// Vacant(_) => unreachable!(),
191/// Occupied(view) => assert_eq!(view.get(), &16),
192/// }
193///
194/// for key in 0..12 {
195/// let hash = compute_hash(map.hasher(), &key);
196/// let value = map.get(&key).cloned();
197/// let key_value = value.as_ref().map(|v| (&key, v));
198///
199/// println!("Key: {} and value: {:?}", key, value);
200///
201/// match map.raw_entry_mut().from_key(&key) {
202/// Occupied(mut o) => assert_eq!(Some(o.get_key_value()), key_value),
203/// Vacant(_) => assert_eq!(value, None),
204/// }
205/// match map.raw_entry_mut().from_key_hashed_nocheck(hash, &key) {
206/// Occupied(mut o) => assert_eq!(Some(o.get_key_value()), key_value),
207/// Vacant(_) => assert_eq!(value, None),
208/// }
209/// match map.raw_entry_mut().from_hash(hash, |q| *q == key) {
210/// Occupied(mut o) => assert_eq!(Some(o.get_key_value()), key_value),
211/// Vacant(_) => assert_eq!(value, None),
212/// }
213/// }
214///
215/// assert_eq!(map.len(), 6);
216/// ```
217pub struct RawEntryBuilderMut<'a, K, V, S, A: Allocator = Global> {
218 map: &'a mut HashMap<K, V, S, A>,
219}
220
221/// A view into a single entry in a map, which may either be vacant or occupied.
222///
223/// This is a lower-level version of [`Entry`].
224///
225/// [`Entry`]: crate::hash_map::Entry
226///
227/// This `enum` is constructed through the [`raw_entry_mut`] method on [`HashMap`],
228/// then calling one of the methods of that [`RawEntryBuilderMut`].
229///
230/// [`raw_entry_mut`]: HashMap::raw_entry_mut
231///
232/// # Examples
233///
234/// ```
235/// use core::hash::{BuildHasher, Hash};
236/// use hashbrown::hash_map::{HashMap, RawEntryMut, RawOccupiedEntryMut};
237///
238/// let mut map = HashMap::new();
239/// map.extend([('a', 1), ('b', 2), ('c', 3)]);
240/// assert_eq!(map.len(), 3);
241///
242/// fn compute_hash<K: Hash + ?Sized, S: BuildHasher>(hash_builder: &S, key: &K) -> u64 {
243/// use core::hash::Hasher;
244/// let mut state = hash_builder.build_hasher();
245/// key.hash(&mut state);
246/// state.finish()
247/// }
248///
249/// // Existing key (insert)
250/// let raw: RawEntryMut<_, _, _> = map.raw_entry_mut().from_key(&'a');
251/// let _raw_o: RawOccupiedEntryMut<_, _, _> = raw.insert('a', 10);
252/// assert_eq!(map.len(), 3);
253///
254/// // Nonexistent key (insert)
255/// map.raw_entry_mut().from_key(&'d').insert('d', 40);
256/// assert_eq!(map.len(), 4);
257///
258/// // Existing key (or_insert)
259/// let hash = compute_hash(map.hasher(), &'b');
260/// let kv = map
261/// .raw_entry_mut()
262/// .from_key_hashed_nocheck(hash, &'b')
263/// .or_insert('b', 20);
264/// assert_eq!(kv, (&mut 'b', &mut 2));
265/// *kv.1 = 20;
266/// assert_eq!(map.len(), 4);
267///
268/// // Nonexistent key (or_insert)
269/// let hash = compute_hash(map.hasher(), &'e');
270/// let kv = map
271/// .raw_entry_mut()
272/// .from_key_hashed_nocheck(hash, &'e')
273/// .or_insert('e', 50);
274/// assert_eq!(kv, (&mut 'e', &mut 50));
275/// assert_eq!(map.len(), 5);
276///
277/// // Existing key (or_insert_with)
278/// let hash = compute_hash(map.hasher(), &'c');
279/// let kv = map
280/// .raw_entry_mut()
281/// .from_hash(hash, |q| q == &'c')
282/// .or_insert_with(|| ('c', 30));
283/// assert_eq!(kv, (&mut 'c', &mut 3));
284/// *kv.1 = 30;
285/// assert_eq!(map.len(), 5);
286///
287/// // Nonexistent key (or_insert_with)
288/// let hash = compute_hash(map.hasher(), &'f');
289/// let kv = map
290/// .raw_entry_mut()
291/// .from_hash(hash, |q| q == &'f')
292/// .or_insert_with(|| ('f', 60));
293/// assert_eq!(kv, (&mut 'f', &mut 60));
294/// assert_eq!(map.len(), 6);
295///
296/// println!("Our HashMap: {:?}", map);
297///
298/// let mut vec: Vec<_> = map.iter().map(|(&k, &v)| (k, v)).collect();
299/// // The `Iter` iterator produces items in arbitrary order, so the
300/// // items must be sorted to test them against a sorted array.
301/// vec.sort_unstable();
302/// assert_eq!(vec, [('a', 10), ('b', 20), ('c', 30), ('d', 40), ('e', 50), ('f', 60)]);
303/// ```
304pub enum RawEntryMut<'a, K, V, S, A: Allocator = Global> {
305 /// An occupied entry.
306 ///
307 /// # Examples
308 ///
309 /// ```
310 /// use hashbrown::{hash_map::RawEntryMut, HashMap};
311 /// let mut map: HashMap<_, _> = [("a", 100), ("b", 200)].into();
312 ///
313 /// match map.raw_entry_mut().from_key(&"a") {
314 /// RawEntryMut::Vacant(_) => unreachable!(),
315 /// RawEntryMut::Occupied(_) => { }
316 /// }
317 /// ```
318 Occupied(RawOccupiedEntryMut<'a, K, V, S, A>),
319 /// A vacant entry.
320 ///
321 /// # Examples
322 ///
323 /// ```
324 /// use hashbrown::{hash_map::RawEntryMut, HashMap};
325 /// let mut map: HashMap<&str, i32> = HashMap::new();
326 ///
327 /// match map.raw_entry_mut().from_key("a") {
328 /// RawEntryMut::Occupied(_) => unreachable!(),
329 /// RawEntryMut::Vacant(_) => { }
330 /// }
331 /// ```
332 Vacant(RawVacantEntryMut<'a, K, V, S, A>),
333}
334
335/// A view into an occupied entry in a `HashMap`.
336/// It is part of the [`RawEntryMut`] enum.
337///
338/// # Examples
339///
340/// ```
341/// use core::hash::{BuildHasher, Hash};
342/// use hashbrown::hash_map::{HashMap, RawEntryMut, RawOccupiedEntryMut};
343///
344/// let mut map = HashMap::new();
345/// map.extend([("a", 10), ("b", 20), ("c", 30)]);
346///
347/// fn compute_hash<K: Hash + ?Sized, S: BuildHasher>(hash_builder: &S, key: &K) -> u64 {
348/// use core::hash::Hasher;
349/// let mut state = hash_builder.build_hasher();
350/// key.hash(&mut state);
351/// state.finish()
352/// }
353///
354/// let _raw_o: RawOccupiedEntryMut<_, _, _> = map.raw_entry_mut().from_key(&"a").insert("a", 100);
355/// assert_eq!(map.len(), 3);
356///
357/// // Existing key (insert and update)
358/// match map.raw_entry_mut().from_key(&"a") {
359/// RawEntryMut::Vacant(_) => unreachable!(),
360/// RawEntryMut::Occupied(mut view) => {
361/// assert_eq!(view.get(), &100);
362/// let v = view.get_mut();
363/// let new_v = (*v) * 10;
364/// *v = new_v;
365/// assert_eq!(view.insert(1111), 1000);
366/// }
367/// }
368///
369/// assert_eq!(map[&"a"], 1111);
370/// assert_eq!(map.len(), 3);
371///
372/// // Existing key (take)
373/// let hash = compute_hash(map.hasher(), &"c");
374/// match map.raw_entry_mut().from_key_hashed_nocheck(hash, &"c") {
375/// RawEntryMut::Vacant(_) => unreachable!(),
376/// RawEntryMut::Occupied(view) => {
377/// assert_eq!(view.remove_entry(), ("c", 30));
378/// }
379/// }
380/// assert_eq!(map.raw_entry().from_key(&"c"), None);
381/// assert_eq!(map.len(), 2);
382///
383/// let hash = compute_hash(map.hasher(), &"b");
384/// match map.raw_entry_mut().from_hash(hash, |q| *q == "b") {
385/// RawEntryMut::Vacant(_) => unreachable!(),
386/// RawEntryMut::Occupied(view) => {
387/// assert_eq!(view.remove_entry(), ("b", 20));
388/// }
389/// }
390/// assert_eq!(map.get(&"b"), None);
391/// assert_eq!(map.len(), 1);
392/// ```
393pub struct RawOccupiedEntryMut<'a, K, V, S, A: Allocator = Global> {
394 elem: Bucket<(K, V)>,
395 table: &'a mut RawTable<(K, V), A>,
396 hash_builder: &'a S,
397}
398
399unsafe impl<K, V, S, A> Send for RawOccupiedEntryMut<'_, K, V, S, A>
400where
401 K: Send,
402 V: Send,
403 S: Send,
404 A: Send + Allocator,
405{
406}
407unsafe impl<K, V, S, A> Sync for RawOccupiedEntryMut<'_, K, V, S, A>
408where
409 K: Sync,
410 V: Sync,
411 S: Sync,
412 A: Sync + Allocator,
413{
414}
415
416/// A view into a vacant entry in a `HashMap`.
417/// It is part of the [`RawEntryMut`] enum.
418///
419/// # Examples
420///
421/// ```
422/// use core::hash::{BuildHasher, Hash};
423/// use hashbrown::hash_map::{HashMap, RawEntryMut, RawVacantEntryMut};
424///
425/// let mut map = HashMap::<&str, i32>::new();
426///
427/// fn compute_hash<K: Hash + ?Sized, S: BuildHasher>(hash_builder: &S, key: &K) -> u64 {
428/// use core::hash::Hasher;
429/// let mut state = hash_builder.build_hasher();
430/// key.hash(&mut state);
431/// state.finish()
432/// }
433///
434/// let raw_v: RawVacantEntryMut<_, _, _> = match map.raw_entry_mut().from_key(&"a") {
435/// RawEntryMut::Vacant(view) => view,
436/// RawEntryMut::Occupied(_) => unreachable!(),
437/// };
438/// raw_v.insert("a", 10);
439/// assert!(map[&"a"] == 10 && map.len() == 1);
440///
441/// // Nonexistent key (insert and update)
442/// let hash = compute_hash(map.hasher(), &"b");
443/// match map.raw_entry_mut().from_key_hashed_nocheck(hash, &"b") {
444/// RawEntryMut::Occupied(_) => unreachable!(),
445/// RawEntryMut::Vacant(view) => {
446/// let (k, value) = view.insert("b", 2);
447/// assert_eq!((*k, *value), ("b", 2));
448/// *value = 20;
449/// }
450/// }
451/// assert!(map[&"b"] == 20 && map.len() == 2);
452///
453/// let hash = compute_hash(map.hasher(), &"c");
454/// match map.raw_entry_mut().from_hash(hash, |q| *q == "c") {
455/// RawEntryMut::Occupied(_) => unreachable!(),
456/// RawEntryMut::Vacant(view) => {
457/// assert_eq!(view.insert("c", 30), (&mut "c", &mut 30));
458/// }
459/// }
460/// assert!(map[&"c"] == 30 && map.len() == 3);
461/// ```
462pub struct RawVacantEntryMut<'a, K, V, S, A: Allocator = Global> {
463 table: &'a mut RawTable<(K, V), A>,
464 hash_builder: &'a S,
465}
466
467/// A builder for computing where in a [`HashMap`] a key-value pair would be stored.
468///
469/// See the [`HashMap::raw_entry`] docs for usage examples.
470///
471/// [`HashMap::raw_entry`]: HashMap::raw_entry
472///
473/// # Examples
474///
475/// ```
476/// use hashbrown::hash_map::{HashMap, RawEntryBuilder};
477/// use core::hash::{BuildHasher, Hash};
478///
479/// let mut map = HashMap::new();
480/// map.extend([(1, 10), (2, 20), (3, 30)]);
481///
482/// fn compute_hash<K: Hash + ?Sized, S: BuildHasher>(hash_builder: &S, key: &K) -> u64 {
483/// use core::hash::Hasher;
484/// let mut state = hash_builder.build_hasher();
485/// key.hash(&mut state);
486/// state.finish()
487/// }
488///
489/// for k in 0..6 {
490/// let hash = compute_hash(map.hasher(), &k);
491/// let v = map.get(&k).cloned();
492/// let kv = v.as_ref().map(|v| (&k, v));
493///
494/// println!("Key: {} and value: {:?}", k, v);
495/// let builder: RawEntryBuilder<_, _, _> = map.raw_entry();
496/// assert_eq!(builder.from_key(&k), kv);
497/// assert_eq!(map.raw_entry().from_hash(hash, |q| *q == k), kv);
498/// assert_eq!(map.raw_entry().from_key_hashed_nocheck(hash, &k), kv);
499/// }
500/// ```
501pub struct RawEntryBuilder<'a, K, V, S, A: Allocator = Global> {
502 map: &'a HashMap<K, V, S, A>,
503}
504
505impl<'a, K, V, S, A: Allocator> RawEntryBuilderMut<'a, K, V, S, A> {
506 /// Creates a `RawEntryMut` from the given key.
507 ///
508 /// # Examples
509 ///
510 /// ```
511 /// use hashbrown::hash_map::{HashMap, RawEntryMut};
512 ///
513 /// let mut map: HashMap<&str, u32> = HashMap::new();
514 /// let key = "a";
515 /// let entry: RawEntryMut<&str, u32, _> = map.raw_entry_mut().from_key(&key);
516 /// entry.insert(key, 100);
517 /// assert_eq!(map[&"a"], 100);
518 /// ```
519 #[cfg_attr(feature = "inline-more", inline)]
520 pub fn from_key<Q>(self, k: &Q) -> RawEntryMut<'a, K, V, S, A>
521 where
522 S: BuildHasher,
523 Q: Hash + Equivalent<K> + ?Sized,
524 {
525 let hash = make_hash::<Q, S>(&self.map.hash_builder, k);
526 self.from_key_hashed_nocheck(hash, k)
527 }
528
529 /// Creates a `RawEntryMut` from the given key and its hash.
530 ///
531 /// # Examples
532 ///
533 /// ```
534 /// use core::hash::{BuildHasher, Hash};
535 /// use hashbrown::hash_map::{HashMap, RawEntryMut};
536 ///
537 /// fn compute_hash<K: Hash + ?Sized, S: BuildHasher>(hash_builder: &S, key: &K) -> u64 {
538 /// use core::hash::Hasher;
539 /// let mut state = hash_builder.build_hasher();
540 /// key.hash(&mut state);
541 /// state.finish()
542 /// }
543 ///
544 /// let mut map: HashMap<&str, u32> = HashMap::new();
545 /// let key = "a";
546 /// let hash = compute_hash(map.hasher(), &key);
547 /// let entry: RawEntryMut<&str, u32, _> = map.raw_entry_mut().from_key_hashed_nocheck(hash, &key);
548 /// entry.insert(key, 100);
549 /// assert_eq!(map[&"a"], 100);
550 /// ```
551 #[inline]
552 pub fn from_key_hashed_nocheck<Q>(self, hash: u64, k: &Q) -> RawEntryMut<'a, K, V, S, A>
553 where
554 Q: Equivalent<K> + ?Sized,
555 {
556 self.from_hash(hash, equivalent(k))
557 }
558}
559
560impl<'a, K, V, S, A: Allocator> RawEntryBuilderMut<'a, K, V, S, A> {
561 /// Creates a `RawEntryMut` from the given hash and matching function.
562 ///
563 /// # Examples
564 ///
565 /// ```
566 /// use core::hash::{BuildHasher, Hash};
567 /// use hashbrown::hash_map::{HashMap, RawEntryMut};
568 ///
569 /// fn compute_hash<K: Hash + ?Sized, S: BuildHasher>(hash_builder: &S, key: &K) -> u64 {
570 /// use core::hash::Hasher;
571 /// let mut state = hash_builder.build_hasher();
572 /// key.hash(&mut state);
573 /// state.finish()
574 /// }
575 ///
576 /// let mut map: HashMap<&str, u32> = HashMap::new();
577 /// let key = "a";
578 /// let hash = compute_hash(map.hasher(), &key);
579 /// let entry: RawEntryMut<&str, u32, _> = map.raw_entry_mut().from_hash(hash, |k| k == &key);
580 /// entry.insert(key, 100);
581 /// assert_eq!(map[&"a"], 100);
582 /// ```
583 #[cfg_attr(feature = "inline-more", inline)]
584 pub fn from_hash<F>(self, hash: u64, is_match: F) -> RawEntryMut<'a, K, V, S, A>
585 where
586 for<'b> F: FnMut(&'b K) -> bool,
587 {
588 self.search(hash, is_match)
589 }
590
591 #[cfg_attr(feature = "inline-more", inline)]
592 fn search<F>(self, hash: u64, mut is_match: F) -> RawEntryMut<'a, K, V, S, A>
593 where
594 for<'b> F: FnMut(&'b K) -> bool,
595 {
596 match self.map.table.find(hash, |(k, _)| is_match(k)) {
597 Some(elem) => RawEntryMut::Occupied(RawOccupiedEntryMut {
598 elem,
599 table: &mut self.map.table,
600 hash_builder: &self.map.hash_builder,
601 }),
602 None => RawEntryMut::Vacant(RawVacantEntryMut {
603 table: &mut self.map.table,
604 hash_builder: &self.map.hash_builder,
605 }),
606 }
607 }
608}
609
610impl<'a, K, V, S, A: Allocator> RawEntryBuilder<'a, K, V, S, A> {
611 /// Access an immutable entry by key.
612 ///
613 /// # Examples
614 ///
615 /// ```
616 /// use hashbrown::HashMap;
617 ///
618 /// let map: HashMap<&str, u32> = [("a", 100), ("b", 200)].into();
619 /// let key = "a";
620 /// assert_eq!(map.raw_entry().from_key(&key), Some((&"a", &100)));
621 /// ```
622 #[cfg_attr(feature = "inline-more", inline)]
623 pub fn from_key<Q>(self, k: &Q) -> Option<(&'a K, &'a V)>
624 where
625 S: BuildHasher,
626 Q: Hash + Equivalent<K> + ?Sized,
627 {
628 let hash = make_hash::<Q, S>(&self.map.hash_builder, k);
629 self.from_key_hashed_nocheck(hash, k)
630 }
631
632 /// Access an immutable entry by a key and its hash.
633 ///
634 /// # Examples
635 ///
636 /// ```
637 /// use core::hash::{BuildHasher, Hash};
638 /// use hashbrown::HashMap;
639 ///
640 /// fn compute_hash<K: Hash + ?Sized, S: BuildHasher>(hash_builder: &S, key: &K) -> u64 {
641 /// use core::hash::Hasher;
642 /// let mut state = hash_builder.build_hasher();
643 /// key.hash(&mut state);
644 /// state.finish()
645 /// }
646 ///
647 /// let map: HashMap<&str, u32> = [("a", 100), ("b", 200)].into();
648 /// let key = "a";
649 /// let hash = compute_hash(map.hasher(), &key);
650 /// assert_eq!(map.raw_entry().from_key_hashed_nocheck(hash, &key), Some((&"a", &100)));
651 /// ```
652 #[cfg_attr(feature = "inline-more", inline)]
653 pub fn from_key_hashed_nocheck<Q>(self, hash: u64, k: &Q) -> Option<(&'a K, &'a V)>
654 where
655 Q: Equivalent<K> + ?Sized,
656 {
657 self.from_hash(hash, equivalent(k))
658 }
659
660 #[cfg_attr(feature = "inline-more", inline)]
661 fn search<F>(self, hash: u64, mut is_match: F) -> Option<(&'a K, &'a V)>
662 where
663 F: FnMut(&K) -> bool,
664 {
665 match self.map.table.get(hash, |(k, _)| is_match(k)) {
666 Some((key, value)) => Some((key, value)),
667 None => None,
668 }
669 }
670
671 /// Access an immutable entry by hash and matching function.
672 ///
673 /// # Examples
674 ///
675 /// ```
676 /// use core::hash::{BuildHasher, Hash};
677 /// use hashbrown::HashMap;
678 ///
679 /// fn compute_hash<K: Hash + ?Sized, S: BuildHasher>(hash_builder: &S, key: &K) -> u64 {
680 /// use core::hash::Hasher;
681 /// let mut state = hash_builder.build_hasher();
682 /// key.hash(&mut state);
683 /// state.finish()
684 /// }
685 ///
686 /// let map: HashMap<&str, u32> = [("a", 100), ("b", 200)].into();
687 /// let key = "a";
688 /// let hash = compute_hash(map.hasher(), &key);
689 /// assert_eq!(map.raw_entry().from_hash(hash, |k| k == &key), Some((&"a", &100)));
690 /// ```
691 #[cfg_attr(feature = "inline-more", inline)]
692 pub fn from_hash<F>(self, hash: u64, is_match: F) -> Option<(&'a K, &'a V)>
693 where
694 F: FnMut(&K) -> bool,
695 {
696 self.search(hash, is_match)
697 }
698}
699
700impl<'a, K, V, S, A: Allocator> RawEntryMut<'a, K, V, S, A> {
701 /// Sets the value of the entry, and returns a `RawOccupiedEntryMut`.
702 ///
703 /// # Examples
704 ///
705 /// ```
706 /// use hashbrown::HashMap;
707 ///
708 /// let mut map: HashMap<&str, u32> = HashMap::new();
709 /// let entry = map.raw_entry_mut().from_key("horseyland").insert("horseyland", 37);
710 ///
711 /// assert_eq!(entry.remove_entry(), ("horseyland", 37));
712 /// ```
713 #[cfg_attr(feature = "inline-more", inline)]
714 pub fn insert(self, key: K, value: V) -> RawOccupiedEntryMut<'a, K, V, S, A>
715 where
716 K: Hash,
717 S: BuildHasher,
718 {
719 match self {
720 RawEntryMut::Occupied(mut entry) => {
721 entry.insert(value);
722 entry
723 }
724 RawEntryMut::Vacant(entry) => entry.insert_entry(key, value),
725 }
726 }
727
728 /// Ensures a value is in the entry by inserting the default if empty, and returns
729 /// mutable references to the key and value in the entry.
730 ///
731 /// # Examples
732 ///
733 /// ```
734 /// use hashbrown::HashMap;
735 ///
736 /// let mut map: HashMap<&str, u32> = HashMap::new();
737 ///
738 /// map.raw_entry_mut().from_key("poneyland").or_insert("poneyland", 3);
739 /// assert_eq!(map["poneyland"], 3);
740 ///
741 /// *map.raw_entry_mut().from_key("poneyland").or_insert("poneyland", 10).1 *= 2;
742 /// assert_eq!(map["poneyland"], 6);
743 /// ```
744 #[cfg_attr(feature = "inline-more", inline)]
745 pub fn or_insert(self, default_key: K, default_val: V) -> (&'a mut K, &'a mut V)
746 where
747 K: Hash,
748 S: BuildHasher,
749 {
750 match self {
751 RawEntryMut::Occupied(entry) => entry.into_key_value(),
752 RawEntryMut::Vacant(entry) => entry.insert(default_key, default_val),
753 }
754 }
755
756 /// Ensures a value is in the entry by inserting the result of the default function if empty,
757 /// and returns mutable references to the key and value in the entry.
758 ///
759 /// # Examples
760 ///
761 /// ```
762 /// use hashbrown::HashMap;
763 ///
764 /// let mut map: HashMap<&str, String> = HashMap::new();
765 ///
766 /// map.raw_entry_mut().from_key("poneyland").or_insert_with(|| {
767 /// ("poneyland", "hoho".to_string())
768 /// });
769 ///
770 /// assert_eq!(map["poneyland"], "hoho".to_string());
771 /// ```
772 #[cfg_attr(feature = "inline-more", inline)]
773 pub fn or_insert_with<F>(self, default: F) -> (&'a mut K, &'a mut V)
774 where
775 F: FnOnce() -> (K, V),
776 K: Hash,
777 S: BuildHasher,
778 {
779 match self {
780 RawEntryMut::Occupied(entry) => entry.into_key_value(),
781 RawEntryMut::Vacant(entry) => {
782 let (k, v) = default();
783 entry.insert(k, v)
784 }
785 }
786 }
787
788 /// Provides in-place mutable access to an occupied entry before any
789 /// potential inserts into the map.
790 ///
791 /// # Examples
792 ///
793 /// ```
794 /// use hashbrown::HashMap;
795 ///
796 /// let mut map: HashMap<&str, u32> = HashMap::new();
797 ///
798 /// map.raw_entry_mut()
799 /// .from_key("poneyland")
800 /// .and_modify(|_k, v| { *v += 1 })
801 /// .or_insert("poneyland", 42);
802 /// assert_eq!(map["poneyland"], 42);
803 ///
804 /// map.raw_entry_mut()
805 /// .from_key("poneyland")
806 /// .and_modify(|_k, v| { *v += 1 })
807 /// .or_insert("poneyland", 0);
808 /// assert_eq!(map["poneyland"], 43);
809 /// ```
810 #[cfg_attr(feature = "inline-more", inline)]
811 pub fn and_modify<F>(self, f: F) -> Self
812 where
813 F: FnOnce(&mut K, &mut V),
814 {
815 match self {
816 RawEntryMut::Occupied(mut entry) => {
817 {
818 let (k, v) = entry.get_key_value_mut();
819 f(k, v);
820 }
821 RawEntryMut::Occupied(entry)
822 }
823 RawEntryMut::Vacant(entry) => RawEntryMut::Vacant(entry),
824 }
825 }
826
827 /// Provides shared access to the key and owned access to the value of
828 /// an occupied entry and allows to replace or remove it based on the
829 /// value of the returned option.
830 ///
831 /// # Examples
832 ///
833 /// ```
834 /// use hashbrown::HashMap;
835 /// use hashbrown::hash_map::RawEntryMut;
836 ///
837 /// let mut map: HashMap<&str, u32> = HashMap::new();
838 ///
839 /// let entry = map
840 /// .raw_entry_mut()
841 /// .from_key("poneyland")
842 /// .and_replace_entry_with(|_k, _v| panic!());
843 ///
844 /// match entry {
845 /// RawEntryMut::Vacant(_) => {},
846 /// RawEntryMut::Occupied(_) => panic!(),
847 /// }
848 ///
849 /// map.insert("poneyland", 42);
850 ///
851 /// let entry = map
852 /// .raw_entry_mut()
853 /// .from_key("poneyland")
854 /// .and_replace_entry_with(|k, v| {
855 /// assert_eq!(k, &"poneyland");
856 /// assert_eq!(v, 42);
857 /// Some(v + 1)
858 /// });
859 ///
860 /// match entry {
861 /// RawEntryMut::Occupied(e) => {
862 /// assert_eq!(e.key(), &"poneyland");
863 /// assert_eq!(e.get(), &43);
864 /// },
865 /// RawEntryMut::Vacant(_) => panic!(),
866 /// }
867 ///
868 /// assert_eq!(map["poneyland"], 43);
869 ///
870 /// let entry = map
871 /// .raw_entry_mut()
872 /// .from_key("poneyland")
873 /// .and_replace_entry_with(|_k, _v| None);
874 ///
875 /// match entry {
876 /// RawEntryMut::Vacant(_) => {},
877 /// RawEntryMut::Occupied(_) => panic!(),
878 /// }
879 ///
880 /// assert!(!map.contains_key("poneyland"));
881 /// ```
882 #[cfg_attr(feature = "inline-more", inline)]
883 pub fn and_replace_entry_with<F>(self, f: F) -> Self
884 where
885 F: FnOnce(&K, V) -> Option<V>,
886 {
887 match self {
888 RawEntryMut::Occupied(entry) => entry.replace_entry_with(f),
889 RawEntryMut::Vacant(_) => self,
890 }
891 }
892}
893
894impl<'a, K, V, S, A: Allocator> RawOccupiedEntryMut<'a, K, V, S, A> {
895 /// Gets a reference to the key in the entry.
896 ///
897 /// # Examples
898 ///
899 /// ```
900 /// use hashbrown::hash_map::{HashMap, RawEntryMut};
901 ///
902 /// let mut map: HashMap<&str, u32> = [("a", 100), ("b", 200)].into();
903 ///
904 /// match map.raw_entry_mut().from_key(&"a") {
905 /// RawEntryMut::Vacant(_) => panic!(),
906 /// RawEntryMut::Occupied(o) => assert_eq!(o.key(), &"a")
907 /// }
908 /// ```
909 #[cfg_attr(feature = "inline-more", inline)]
910 pub fn key(&self) -> &K {
911 unsafe { &self.elem.as_ref().0 }
912 }
913
914 /// Gets a mutable reference to the key in the entry.
915 ///
916 /// # Examples
917 ///
918 /// ```
919 /// use hashbrown::hash_map::{HashMap, RawEntryMut};
920 /// use std::rc::Rc;
921 ///
922 /// let key_one = Rc::new("a");
923 /// let key_two = Rc::new("a");
924 ///
925 /// let mut map: HashMap<Rc<&str>, u32> = HashMap::new();
926 /// map.insert(key_one.clone(), 10);
927 ///
928 /// assert_eq!(map[&key_one], 10);
929 /// assert!(Rc::strong_count(&key_one) == 2 && Rc::strong_count(&key_two) == 1);
930 ///
931 /// match map.raw_entry_mut().from_key(&key_one) {
932 /// RawEntryMut::Vacant(_) => panic!(),
933 /// RawEntryMut::Occupied(mut o) => {
934 /// *o.key_mut() = key_two.clone();
935 /// }
936 /// }
937 /// assert_eq!(map[&key_two], 10);
938 /// assert!(Rc::strong_count(&key_one) == 1 && Rc::strong_count(&key_two) == 2);
939 /// ```
940 #[cfg_attr(feature = "inline-more", inline)]
941 pub fn key_mut(&mut self) -> &mut K {
942 unsafe { &mut self.elem.as_mut().0 }
943 }
944
945 /// Converts the entry into a mutable reference to the key in the entry
946 /// with a lifetime bound to the map itself.
947 ///
948 /// # Examples
949 ///
950 /// ```
951 /// use hashbrown::hash_map::{HashMap, RawEntryMut};
952 /// use std::rc::Rc;
953 ///
954 /// let key_one = Rc::new("a");
955 /// let key_two = Rc::new("a");
956 ///
957 /// let mut map: HashMap<Rc<&str>, u32> = HashMap::new();
958 /// map.insert(key_one.clone(), 10);
959 ///
960 /// assert_eq!(map[&key_one], 10);
961 /// assert!(Rc::strong_count(&key_one) == 2 && Rc::strong_count(&key_two) == 1);
962 ///
963 /// let inside_key: &mut Rc<&str>;
964 ///
965 /// match map.raw_entry_mut().from_key(&key_one) {
966 /// RawEntryMut::Vacant(_) => panic!(),
967 /// RawEntryMut::Occupied(o) => inside_key = o.into_key(),
968 /// }
969 /// *inside_key = key_two.clone();
970 ///
971 /// assert_eq!(map[&key_two], 10);
972 /// assert!(Rc::strong_count(&key_one) == 1 && Rc::strong_count(&key_two) == 2);
973 /// ```
974 #[cfg_attr(feature = "inline-more", inline)]
975 pub fn into_key(self) -> &'a mut K {
976 unsafe { &mut self.elem.as_mut().0 }
977 }
978
979 /// Gets a reference to the value in the entry.
980 ///
981 /// # Examples
982 ///
983 /// ```
984 /// use hashbrown::hash_map::{HashMap, RawEntryMut};
985 ///
986 /// let mut map: HashMap<&str, u32> = [("a", 100), ("b", 200)].into();
987 ///
988 /// match map.raw_entry_mut().from_key(&"a") {
989 /// RawEntryMut::Vacant(_) => panic!(),
990 /// RawEntryMut::Occupied(o) => assert_eq!(o.get(), &100),
991 /// }
992 /// ```
993 #[cfg_attr(feature = "inline-more", inline)]
994 pub fn get(&self) -> &V {
995 unsafe { &self.elem.as_ref().1 }
996 }
997
998 /// Converts the `OccupiedEntry` into a mutable reference to the value in the entry
999 /// with a lifetime bound to the map itself.
1000 ///
1001 /// # Examples
1002 ///
1003 /// ```
1004 /// use hashbrown::hash_map::{HashMap, RawEntryMut};
1005 ///
1006 /// let mut map: HashMap<&str, u32> = [("a", 100), ("b", 200)].into();
1007 ///
1008 /// let value: &mut u32;
1009 ///
1010 /// match map.raw_entry_mut().from_key(&"a") {
1011 /// RawEntryMut::Vacant(_) => panic!(),
1012 /// RawEntryMut::Occupied(o) => value = o.into_mut(),
1013 /// }
1014 /// *value += 900;
1015 ///
1016 /// assert_eq!(map[&"a"], 1000);
1017 /// ```
1018 #[cfg_attr(feature = "inline-more", inline)]
1019 pub fn into_mut(self) -> &'a mut V {
1020 unsafe { &mut self.elem.as_mut().1 }
1021 }
1022
1023 /// Gets a mutable reference to the value in the entry.
1024 ///
1025 /// # Examples
1026 ///
1027 /// ```
1028 /// use hashbrown::hash_map::{HashMap, RawEntryMut};
1029 ///
1030 /// let mut map: HashMap<&str, u32> = [("a", 100), ("b", 200)].into();
1031 ///
1032 /// match map.raw_entry_mut().from_key(&"a") {
1033 /// RawEntryMut::Vacant(_) => panic!(),
1034 /// RawEntryMut::Occupied(mut o) => *o.get_mut() += 900,
1035 /// }
1036 ///
1037 /// assert_eq!(map[&"a"], 1000);
1038 /// ```
1039 #[cfg_attr(feature = "inline-more", inline)]
1040 pub fn get_mut(&mut self) -> &mut V {
1041 unsafe { &mut self.elem.as_mut().1 }
1042 }
1043
1044 /// Gets a reference to the key and value in the entry.
1045 ///
1046 /// # Examples
1047 ///
1048 /// ```
1049 /// use hashbrown::hash_map::{HashMap, RawEntryMut};
1050 ///
1051 /// let mut map: HashMap<&str, u32> = [("a", 100), ("b", 200)].into();
1052 ///
1053 /// match map.raw_entry_mut().from_key(&"a") {
1054 /// RawEntryMut::Vacant(_) => panic!(),
1055 /// RawEntryMut::Occupied(o) => assert_eq!(o.get_key_value(), (&"a", &100)),
1056 /// }
1057 /// ```
1058 #[cfg_attr(feature = "inline-more", inline)]
1059 pub fn get_key_value(&self) -> (&K, &V) {
1060 unsafe {
1061 let (key, value) = self.elem.as_ref();
1062 (key, value)
1063 }
1064 }
1065
1066 /// Gets a mutable reference to the key and value in the entry.
1067 ///
1068 /// # Examples
1069 ///
1070 /// ```
1071 /// use hashbrown::hash_map::{HashMap, RawEntryMut};
1072 /// use std::rc::Rc;
1073 ///
1074 /// let key_one = Rc::new("a");
1075 /// let key_two = Rc::new("a");
1076 ///
1077 /// let mut map: HashMap<Rc<&str>, u32> = HashMap::new();
1078 /// map.insert(key_one.clone(), 10);
1079 ///
1080 /// assert_eq!(map[&key_one], 10);
1081 /// assert!(Rc::strong_count(&key_one) == 2 && Rc::strong_count(&key_two) == 1);
1082 ///
1083 /// match map.raw_entry_mut().from_key(&key_one) {
1084 /// RawEntryMut::Vacant(_) => panic!(),
1085 /// RawEntryMut::Occupied(mut o) => {
1086 /// let (inside_key, inside_value) = o.get_key_value_mut();
1087 /// *inside_key = key_two.clone();
1088 /// *inside_value = 100;
1089 /// }
1090 /// }
1091 /// assert_eq!(map[&key_two], 100);
1092 /// assert!(Rc::strong_count(&key_one) == 1 && Rc::strong_count(&key_two) == 2);
1093 /// ```
1094 #[cfg_attr(feature = "inline-more", inline)]
1095 pub fn get_key_value_mut(&mut self) -> (&mut K, &mut V) {
1096 unsafe {
1097 let &mut (ref mut key, ref mut value) = self.elem.as_mut();
1098 (key, value)
1099 }
1100 }
1101
1102 /// Converts the `OccupiedEntry` into a mutable reference to the key and value in the entry
1103 /// with a lifetime bound to the map itself.
1104 ///
1105 /// # Examples
1106 ///
1107 /// ```
1108 /// use hashbrown::hash_map::{HashMap, RawEntryMut};
1109 /// use std::rc::Rc;
1110 ///
1111 /// let key_one = Rc::new("a");
1112 /// let key_two = Rc::new("a");
1113 ///
1114 /// let mut map: HashMap<Rc<&str>, u32> = HashMap::new();
1115 /// map.insert(key_one.clone(), 10);
1116 ///
1117 /// assert_eq!(map[&key_one], 10);
1118 /// assert!(Rc::strong_count(&key_one) == 2 && Rc::strong_count(&key_two) == 1);
1119 ///
1120 /// let inside_key: &mut Rc<&str>;
1121 /// let inside_value: &mut u32;
1122 /// match map.raw_entry_mut().from_key(&key_one) {
1123 /// RawEntryMut::Vacant(_) => panic!(),
1124 /// RawEntryMut::Occupied(o) => {
1125 /// let tuple = o.into_key_value();
1126 /// inside_key = tuple.0;
1127 /// inside_value = tuple.1;
1128 /// }
1129 /// }
1130 /// *inside_key = key_two.clone();
1131 /// *inside_value = 100;
1132 /// assert_eq!(map[&key_two], 100);
1133 /// assert!(Rc::strong_count(&key_one) == 1 && Rc::strong_count(&key_two) == 2);
1134 /// ```
1135 #[cfg_attr(feature = "inline-more", inline)]
1136 pub fn into_key_value(self) -> (&'a mut K, &'a mut V) {
1137 unsafe {
1138 let &mut (ref mut key, ref mut value) = self.elem.as_mut();
1139 (key, value)
1140 }
1141 }
1142
1143 /// Sets the value of the entry, and returns the entry's old value.
1144 ///
1145 /// # Examples
1146 ///
1147 /// ```
1148 /// use hashbrown::hash_map::{HashMap, RawEntryMut};
1149 ///
1150 /// let mut map: HashMap<&str, u32> = [("a", 100), ("b", 200)].into();
1151 ///
1152 /// match map.raw_entry_mut().from_key(&"a") {
1153 /// RawEntryMut::Vacant(_) => panic!(),
1154 /// RawEntryMut::Occupied(mut o) => assert_eq!(o.insert(1000), 100),
1155 /// }
1156 ///
1157 /// assert_eq!(map[&"a"], 1000);
1158 /// ```
1159 #[cfg_attr(feature = "inline-more", inline)]
1160 pub fn insert(&mut self, value: V) -> V {
1161 mem::replace(self.get_mut(), value)
1162 }
1163
1164 /// Sets the value of the entry, and returns the entry's old value.
1165 ///
1166 /// # Examples
1167 ///
1168 /// ```
1169 /// use hashbrown::hash_map::{HashMap, RawEntryMut};
1170 /// use std::rc::Rc;
1171 ///
1172 /// let key_one = Rc::new("a");
1173 /// let key_two = Rc::new("a");
1174 ///
1175 /// let mut map: HashMap<Rc<&str>, u32> = HashMap::new();
1176 /// map.insert(key_one.clone(), 10);
1177 ///
1178 /// assert_eq!(map[&key_one], 10);
1179 /// assert!(Rc::strong_count(&key_one) == 2 && Rc::strong_count(&key_two) == 1);
1180 ///
1181 /// match map.raw_entry_mut().from_key(&key_one) {
1182 /// RawEntryMut::Vacant(_) => panic!(),
1183 /// RawEntryMut::Occupied(mut o) => {
1184 /// let old_key = o.insert_key(key_two.clone());
1185 /// assert!(Rc::ptr_eq(&old_key, &key_one));
1186 /// }
1187 /// }
1188 /// assert_eq!(map[&key_two], 10);
1189 /// assert!(Rc::strong_count(&key_one) == 1 && Rc::strong_count(&key_two) == 2);
1190 /// ```
1191 #[cfg_attr(feature = "inline-more", inline)]
1192 pub fn insert_key(&mut self, key: K) -> K {
1193 mem::replace(self.key_mut(), key)
1194 }
1195
1196 /// Takes the value out of the entry, and returns it.
1197 ///
1198 /// # Examples
1199 ///
1200 /// ```
1201 /// use hashbrown::hash_map::{HashMap, RawEntryMut};
1202 ///
1203 /// let mut map: HashMap<&str, u32> = [("a", 100), ("b", 200)].into();
1204 ///
1205 /// match map.raw_entry_mut().from_key(&"a") {
1206 /// RawEntryMut::Vacant(_) => panic!(),
1207 /// RawEntryMut::Occupied(o) => assert_eq!(o.remove(), 100),
1208 /// }
1209 /// assert_eq!(map.get(&"a"), None);
1210 /// ```
1211 #[cfg_attr(feature = "inline-more", inline)]
1212 pub fn remove(self) -> V {
1213 self.remove_entry().1
1214 }
1215
1216 /// Take the ownership of the key and value from the map.
1217 ///
1218 /// # Examples
1219 ///
1220 /// ```
1221 /// use hashbrown::hash_map::{HashMap, RawEntryMut};
1222 ///
1223 /// let mut map: HashMap<&str, u32> = [("a", 100), ("b", 200)].into();
1224 ///
1225 /// match map.raw_entry_mut().from_key(&"a") {
1226 /// RawEntryMut::Vacant(_) => panic!(),
1227 /// RawEntryMut::Occupied(o) => assert_eq!(o.remove_entry(), ("a", 100)),
1228 /// }
1229 /// assert_eq!(map.get(&"a"), None);
1230 /// ```
1231 #[cfg_attr(feature = "inline-more", inline)]
1232 pub fn remove_entry(self) -> (K, V) {
1233 unsafe { self.table.remove(self.elem).0 }
1234 }
1235
1236 /// Provides shared access to the key and owned access to the value of
1237 /// the entry and allows to replace or remove it based on the
1238 /// value of the returned option.
1239 ///
1240 /// # Examples
1241 ///
1242 /// ```
1243 /// use hashbrown::hash_map::{HashMap, RawEntryMut};
1244 ///
1245 /// let mut map: HashMap<&str, u32> = [("a", 100), ("b", 200)].into();
1246 ///
1247 /// let raw_entry = match map.raw_entry_mut().from_key(&"a") {
1248 /// RawEntryMut::Vacant(_) => panic!(),
1249 /// RawEntryMut::Occupied(o) => o.replace_entry_with(|k, v| {
1250 /// assert_eq!(k, &"a");
1251 /// assert_eq!(v, 100);
1252 /// Some(v + 900)
1253 /// }),
1254 /// };
1255 /// let raw_entry = match raw_entry {
1256 /// RawEntryMut::Vacant(_) => panic!(),
1257 /// RawEntryMut::Occupied(o) => o.replace_entry_with(|k, v| {
1258 /// assert_eq!(k, &"a");
1259 /// assert_eq!(v, 1000);
1260 /// None
1261 /// }),
1262 /// };
1263 /// match raw_entry {
1264 /// RawEntryMut::Vacant(_) => { },
1265 /// RawEntryMut::Occupied(_) => panic!(),
1266 /// };
1267 /// assert_eq!(map.get(&"a"), None);
1268 /// ```
1269 #[cfg_attr(feature = "inline-more", inline)]
1270 pub fn replace_entry_with<F>(self, f: F) -> RawEntryMut<'a, K, V, S, A>
1271 where
1272 F: FnOnce(&K, V) -> Option<V>,
1273 {
1274 unsafe {
1275 let tag = self
1276 .table
1277 .replace_bucket_with(self.elem.clone(), |(key, value)| {
1278 f(&key, value).map(|new_value| (key, new_value))
1279 });
1280
1281 if tag.is_none() {
1282 RawEntryMut::Occupied(self)
1283 } else {
1284 RawEntryMut::Vacant(RawVacantEntryMut {
1285 table: self.table,
1286 hash_builder: self.hash_builder,
1287 })
1288 }
1289 }
1290 }
1291}
1292
1293impl<'a, K, V, S, A: Allocator> RawVacantEntryMut<'a, K, V, S, A> {
1294 /// Sets the value of the entry with the `VacantEntry`'s key,
1295 /// and returns a mutable reference to it.
1296 ///
1297 /// # Examples
1298 ///
1299 /// ```
1300 /// use hashbrown::hash_map::{HashMap, RawEntryMut};
1301 ///
1302 /// let mut map: HashMap<&str, u32> = [("a", 100), ("b", 200)].into();
1303 ///
1304 /// match map.raw_entry_mut().from_key(&"c") {
1305 /// RawEntryMut::Occupied(_) => panic!(),
1306 /// RawEntryMut::Vacant(v) => assert_eq!(v.insert("c", 300), (&mut "c", &mut 300)),
1307 /// }
1308 ///
1309 /// assert_eq!(map[&"c"], 300);
1310 /// ```
1311 #[cfg_attr(feature = "inline-more", inline)]
1312 pub fn insert(self, key: K, value: V) -> (&'a mut K, &'a mut V)
1313 where
1314 K: Hash,
1315 S: BuildHasher,
1316 {
1317 let hash = make_hash::<K, S>(self.hash_builder, &key);
1318 self.insert_hashed_nocheck(hash, key, value)
1319 }
1320
1321 /// Sets the value of the entry with the `VacantEntry`'s key,
1322 /// and returns a mutable reference to it.
1323 ///
1324 /// # Examples
1325 ///
1326 /// ```
1327 /// use core::hash::{BuildHasher, Hash};
1328 /// use hashbrown::hash_map::{HashMap, RawEntryMut};
1329 ///
1330 /// fn compute_hash<K: Hash + ?Sized, S: BuildHasher>(hash_builder: &S, key: &K) -> u64 {
1331 /// use core::hash::Hasher;
1332 /// let mut state = hash_builder.build_hasher();
1333 /// key.hash(&mut state);
1334 /// state.finish()
1335 /// }
1336 ///
1337 /// let mut map: HashMap<&str, u32> = [("a", 100), ("b", 200)].into();
1338 /// let key = "c";
1339 /// let hash = compute_hash(map.hasher(), &key);
1340 ///
1341 /// match map.raw_entry_mut().from_key_hashed_nocheck(hash, &key) {
1342 /// RawEntryMut::Occupied(_) => panic!(),
1343 /// RawEntryMut::Vacant(v) => assert_eq!(
1344 /// v.insert_hashed_nocheck(hash, key, 300),
1345 /// (&mut "c", &mut 300)
1346 /// ),
1347 /// }
1348 ///
1349 /// assert_eq!(map[&"c"], 300);
1350 /// ```
1351 #[cfg_attr(feature = "inline-more", inline)]
1352 pub fn insert_hashed_nocheck(self, hash: u64, key: K, value: V) -> (&'a mut K, &'a mut V)
1353 where
1354 K: Hash,
1355 S: BuildHasher,
1356 {
1357 let &mut (ref mut k, ref mut v) = self.table.insert_entry(
1358 hash,
1359 (key, value),
1360 make_hasher::<_, V, S>(self.hash_builder),
1361 );
1362 (k, v)
1363 }
1364
1365 /// Set the value of an entry with a custom hasher function.
1366 ///
1367 /// # Examples
1368 ///
1369 /// ```
1370 /// use core::hash::{BuildHasher, Hash};
1371 /// use hashbrown::hash_map::{HashMap, RawEntryMut};
1372 ///
1373 /// fn make_hasher<K, S>(hash_builder: &S) -> impl Fn(&K) -> u64 + '_
1374 /// where
1375 /// K: Hash + ?Sized,
1376 /// S: BuildHasher,
1377 /// {
1378 /// move |key: &K| {
1379 /// use core::hash::Hasher;
1380 /// let mut state = hash_builder.build_hasher();
1381 /// key.hash(&mut state);
1382 /// state.finish()
1383 /// }
1384 /// }
1385 ///
1386 /// let mut map: HashMap<&str, u32> = HashMap::new();
1387 /// let key = "a";
1388 /// let hash_builder = map.hasher().clone();
1389 /// let hash = make_hasher(&hash_builder)(&key);
1390 ///
1391 /// match map.raw_entry_mut().from_hash(hash, |q| q == &key) {
1392 /// RawEntryMut::Occupied(_) => panic!(),
1393 /// RawEntryMut::Vacant(v) => assert_eq!(
1394 /// v.insert_with_hasher(hash, key, 100, make_hasher(&hash_builder)),
1395 /// (&mut "a", &mut 100)
1396 /// ),
1397 /// }
1398 /// map.extend([("b", 200), ("c", 300), ("d", 400), ("e", 500), ("f", 600)]);
1399 /// assert_eq!(map[&"a"], 100);
1400 /// ```
1401 #[cfg_attr(feature = "inline-more", inline)]
1402 pub fn insert_with_hasher<H>(
1403 self,
1404 hash: u64,
1405 key: K,
1406 value: V,
1407 hasher: H,
1408 ) -> (&'a mut K, &'a mut V)
1409 where
1410 H: Fn(&K) -> u64,
1411 {
1412 let &mut (ref mut k, ref mut v) = self
1413 .table
1414 .insert_entry(hash, (key, value), |x| hasher(&x.0));
1415 (k, v)
1416 }
1417
1418 #[cfg_attr(feature = "inline-more", inline)]
1419 fn insert_entry(self, key: K, value: V) -> RawOccupiedEntryMut<'a, K, V, S, A>
1420 where
1421 K: Hash,
1422 S: BuildHasher,
1423 {
1424 let hash = make_hash::<K, S>(self.hash_builder, &key);
1425 let elem = self.table.insert(
1426 hash,
1427 (key, value),
1428 make_hasher::<_, V, S>(self.hash_builder),
1429 );
1430 RawOccupiedEntryMut {
1431 elem,
1432 table: self.table,
1433 hash_builder: self.hash_builder,
1434 }
1435 }
1436}
1437
1438impl<K, V, S, A: Allocator> Debug for RawEntryBuilderMut<'_, K, V, S, A> {
1439 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1440 f.debug_struct("RawEntryBuilder").finish()
1441 }
1442}
1443
1444impl<K: Debug, V: Debug, S, A: Allocator> Debug for RawEntryMut<'_, K, V, S, A> {
1445 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1446 match *self {
1447 RawEntryMut::Vacant(ref v) => f.debug_tuple("RawEntry").field(v).finish(),
1448 RawEntryMut::Occupied(ref o) => f.debug_tuple("RawEntry").field(o).finish(),
1449 }
1450 }
1451}
1452
1453impl<K: Debug, V: Debug, S, A: Allocator> Debug for RawOccupiedEntryMut<'_, K, V, S, A> {
1454 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1455 f.debug_struct("RawOccupiedEntryMut")
1456 .field("key", self.key())
1457 .field("value", self.get())
1458 .finish()
1459 }
1460}
1461
1462impl<K, V, S, A: Allocator> Debug for RawVacantEntryMut<'_, K, V, S, A> {
1463 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1464 f.debug_struct("RawVacantEntryMut").finish()
1465 }
1466}
1467
1468impl<K, V, S, A: Allocator> Debug for RawEntryBuilder<'_, K, V, S, A> {
1469 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1470 f.debug_struct("RawEntryBuilder").finish()
1471 }
1472}
1473
1474#[cfg(test)]
1475mod test_map {
1476 use super::HashMap;
1477 use super::RawEntryMut;
1478
1479 #[test]
1480 fn test_raw_occupied_entry_replace_entry_with() {
1481 let mut a = HashMap::new();
1482
1483 let key = "a key";
1484 let value = "an initial value";
1485 let new_value = "a new value";
1486
1487 let entry = a
1488 .raw_entry_mut()
1489 .from_key(&key)
1490 .insert(key, value)
1491 .replace_entry_with(|k, v| {
1492 assert_eq!(k, &key);
1493 assert_eq!(v, value);
1494 Some(new_value)
1495 });
1496
1497 match entry {
1498 RawEntryMut::Occupied(e) => {
1499 assert_eq!(e.key(), &key);
1500 assert_eq!(e.get(), &new_value);
1501 }
1502 RawEntryMut::Vacant(_) => panic!(),
1503 }
1504
1505 assert_eq!(a[key], new_value);
1506 assert_eq!(a.len(), 1);
1507
1508 let entry = match a.raw_entry_mut().from_key(&key) {
1509 RawEntryMut::Occupied(e) => e.replace_entry_with(|k, v| {
1510 assert_eq!(k, &key);
1511 assert_eq!(v, new_value);
1512 None
1513 }),
1514 RawEntryMut::Vacant(_) => panic!(),
1515 };
1516
1517 match entry {
1518 RawEntryMut::Vacant(_) => {}
1519 RawEntryMut::Occupied(_) => panic!(),
1520 }
1521
1522 assert!(!a.contains_key(key));
1523 assert_eq!(a.len(), 0);
1524 }
1525
1526 #[test]
1527 fn test_raw_entry_and_replace_entry_with() {
1528 let mut a = HashMap::new();
1529
1530 let key = "a key";
1531 let value = "an initial value";
1532 let new_value = "a new value";
1533
1534 let entry = a
1535 .raw_entry_mut()
1536 .from_key(&key)
1537 .and_replace_entry_with(|_, _| panic!());
1538
1539 match entry {
1540 RawEntryMut::Vacant(_) => {}
1541 RawEntryMut::Occupied(_) => panic!(),
1542 }
1543
1544 a.insert(key, value);
1545
1546 let entry = a
1547 .raw_entry_mut()
1548 .from_key(&key)
1549 .and_replace_entry_with(|k, v| {
1550 assert_eq!(k, &key);
1551 assert_eq!(v, value);
1552 Some(new_value)
1553 });
1554
1555 match entry {
1556 RawEntryMut::Occupied(e) => {
1557 assert_eq!(e.key(), &key);
1558 assert_eq!(e.get(), &new_value);
1559 }
1560 RawEntryMut::Vacant(_) => panic!(),
1561 }
1562
1563 assert_eq!(a[key], new_value);
1564 assert_eq!(a.len(), 1);
1565
1566 let entry = a
1567 .raw_entry_mut()
1568 .from_key(&key)
1569 .and_replace_entry_with(|k, v| {
1570 assert_eq!(k, &key);
1571 assert_eq!(v, new_value);
1572 None
1573 });
1574
1575 match entry {
1576 RawEntryMut::Vacant(_) => {}
1577 RawEntryMut::Occupied(_) => panic!(),
1578 }
1579
1580 assert!(!a.contains_key(key));
1581 assert_eq!(a.len(), 0);
1582 }
1583
1584 #[test]
1585 fn test_raw_entry() {
1586 use super::RawEntryMut::{Occupied, Vacant};
1587
1588 let xs = [(1_i32, 10_i32), (2, 20), (3, 30), (4, 40), (5, 50), (6, 60)];
1589
1590 let mut map: HashMap<_, _> = xs.iter().copied().collect();
1591
1592 let compute_hash = |map: &HashMap<i32, i32>, k: i32| -> u64 {
1593 super::make_hash::<i32, _>(map.hasher(), &k)
1594 };
1595
1596 // Existing key (insert)
1597 match map.raw_entry_mut().from_key(&1) {
1598 Vacant(_) => unreachable!(),
1599 Occupied(mut view) => {
1600 assert_eq!(view.get(), &10);
1601 assert_eq!(view.insert(100), 10);
1602 }
1603 }
1604 let hash1 = compute_hash(&map, 1);
1605 assert_eq!(map.raw_entry().from_key(&1).unwrap(), (&1, &100));
1606 assert_eq!(
1607 map.raw_entry().from_hash(hash1, |k| *k == 1).unwrap(),
1608 (&1, &100)
1609 );
1610 assert_eq!(
1611 map.raw_entry().from_key_hashed_nocheck(hash1, &1).unwrap(),
1612 (&1, &100)
1613 );
1614 assert_eq!(map.len(), 6);
1615
1616 // Existing key (update)
1617 match map.raw_entry_mut().from_key(&2) {
1618 Vacant(_) => unreachable!(),
1619 Occupied(mut view) => {
1620 let v = view.get_mut();
1621 let new_v = (*v) * 10;
1622 *v = new_v;
1623 }
1624 }
1625 let hash2 = compute_hash(&map, 2);
1626 assert_eq!(map.raw_entry().from_key(&2).unwrap(), (&2, &200));
1627 assert_eq!(
1628 map.raw_entry().from_hash(hash2, |k| *k == 2).unwrap(),
1629 (&2, &200)
1630 );
1631 assert_eq!(
1632 map.raw_entry().from_key_hashed_nocheck(hash2, &2).unwrap(),
1633 (&2, &200)
1634 );
1635 assert_eq!(map.len(), 6);
1636
1637 // Existing key (take)
1638 let hash3 = compute_hash(&map, 3);
1639 match map.raw_entry_mut().from_key_hashed_nocheck(hash3, &3) {
1640 Vacant(_) => unreachable!(),
1641 Occupied(view) => {
1642 assert_eq!(view.remove_entry(), (3, 30));
1643 }
1644 }
1645 assert_eq!(map.raw_entry().from_key(&3), None);
1646 assert_eq!(map.raw_entry().from_hash(hash3, |k| *k == 3), None);
1647 assert_eq!(map.raw_entry().from_key_hashed_nocheck(hash3, &3), None);
1648 assert_eq!(map.len(), 5);
1649
1650 // Nonexistent key (insert)
1651 match map.raw_entry_mut().from_key(&10) {
1652 Occupied(_) => unreachable!(),
1653 Vacant(view) => {
1654 assert_eq!(view.insert(10, 1000), (&mut 10, &mut 1000));
1655 }
1656 }
1657 assert_eq!(map.raw_entry().from_key(&10).unwrap(), (&10, &1000));
1658 assert_eq!(map.len(), 6);
1659
1660 // Ensure all lookup methods produce equivalent results.
1661 for k in 0..12 {
1662 let hash = compute_hash(&map, k);
1663 let v = map.get(&k).copied();
1664 let kv = v.as_ref().map(|v| (&k, v));
1665
1666 assert_eq!(map.raw_entry().from_key(&k), kv);
1667 assert_eq!(map.raw_entry().from_hash(hash, |q| *q == k), kv);
1668 assert_eq!(map.raw_entry().from_key_hashed_nocheck(hash, &k), kv);
1669
1670 match map.raw_entry_mut().from_key(&k) {
1671 Occupied(o) => assert_eq!(Some(o.get_key_value()), kv),
1672 Vacant(_) => assert_eq!(v, None),
1673 }
1674 match map.raw_entry_mut().from_key_hashed_nocheck(hash, &k) {
1675 Occupied(o) => assert_eq!(Some(o.get_key_value()), kv),
1676 Vacant(_) => assert_eq!(v, None),
1677 }
1678 match map.raw_entry_mut().from_hash(hash, |q| *q == k) {
1679 Occupied(o) => assert_eq!(Some(o.get_key_value()), kv),
1680 Vacant(_) => assert_eq!(v, None),
1681 }
1682 }
1683 }
1684
1685 #[test]
1686 fn test_key_without_hash_impl() {
1687 #[derive(Debug)]
1688 struct IntWrapper(u64);
1689
1690 let mut m: HashMap<IntWrapper, (), ()> = HashMap::default();
1691 {
1692 assert!(m.raw_entry().from_hash(0, |k| k.0 == 0).is_none());
1693 }
1694 {
1695 let vacant_entry = match m.raw_entry_mut().from_hash(0, |k| k.0 == 0) {
1696 RawEntryMut::Occupied(..) => panic!("Found entry for key 0"),
1697 RawEntryMut::Vacant(e) => e,
1698 };
1699 vacant_entry.insert_with_hasher(0, IntWrapper(0), (), |k| k.0);
1700 }
1701 {
1702 assert!(m.raw_entry().from_hash(0, |k| k.0 == 0).is_some());
1703 assert!(m.raw_entry().from_hash(1, |k| k.0 == 1).is_none());
1704 assert!(m.raw_entry().from_hash(2, |k| k.0 == 2).is_none());
1705 }
1706 {
1707 let vacant_entry = match m.raw_entry_mut().from_hash(1, |k| k.0 == 1) {
1708 RawEntryMut::Occupied(..) => panic!("Found entry for key 1"),
1709 RawEntryMut::Vacant(e) => e,
1710 };
1711 vacant_entry.insert_with_hasher(1, IntWrapper(1), (), |k| k.0);
1712 }
1713 {
1714 assert!(m.raw_entry().from_hash(0, |k| k.0 == 0).is_some());
1715 assert!(m.raw_entry().from_hash(1, |k| k.0 == 1).is_some());
1716 assert!(m.raw_entry().from_hash(2, |k| k.0 == 2).is_none());
1717 }
1718 {
1719 let occupied_entry = match m.raw_entry_mut().from_hash(0, |k| k.0 == 0) {
1720 RawEntryMut::Occupied(e) => e,
1721 RawEntryMut::Vacant(..) => panic!("Couldn't find entry for key 0"),
1722 };
1723 occupied_entry.remove();
1724 }
1725 assert!(m.raw_entry().from_hash(0, |k| k.0 == 0).is_none());
1726 assert!(m.raw_entry().from_hash(1, |k| k.0 == 1).is_some());
1727 assert!(m.raw_entry().from_hash(2, |k| k.0 == 2).is_none());
1728 }
1729}