Coverage Report

Created: 2025-12-28 06:31

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