hashbrown/table.rs
1use core::{fmt, iter::FusedIterator, marker::PhantomData, ptr::NonNull};
2
3use crate::{
4 TryReserveError,
5 alloc::{Allocator, Global},
6 control::Tag,
7 raw::{
8 Bucket, FullBucketsIndices, RawDrain, RawExtractIf, RawIntoIter, RawIter, RawIterHash,
9 RawIterHashIndices, RawTable,
10 },
11};
12
13/// Low-level hash table with explicit hashing.
14///
15/// The primary use case for this type over [`HashMap`] or [`HashSet`] is to
16/// support types that do not implement the [`Hash`] and [`Eq`] traits, but
17/// instead require additional data not contained in the key itself to compute a
18/// hash and compare two elements for equality.
19///
20/// Examples of when this can be useful include:
21/// - An `IndexMap` implementation where indices into a `Vec` are stored as
22/// elements in a `HashTable<usize>`. Hashing and comparing the elements
23/// requires indexing the associated `Vec` to get the actual value referred to
24/// by the index.
25/// - Avoiding re-computing a hash when it is already known.
26/// - Mutating the key of an element in a way that doesn't affect its hash.
27///
28/// To achieve this, `HashTable` methods that search for an element in the table
29/// require a hash value and equality function to be explicitly passed in as
30/// arguments. The method will then iterate over the elements with the given
31/// hash and call the equality function on each of them, until a match is found.
32///
33/// In most cases, a `HashTable` will not be exposed directly in an API. It will
34/// instead be wrapped in a helper type which handles the work of calculating
35/// hash values and comparing elements.
36///
37/// Due to its low-level nature, this type provides fewer guarantees than
38/// [`HashMap`] and [`HashSet`]. Specifically, the API allows you to shoot
39/// yourself in the foot by having multiple elements with identical keys in the
40/// table. The table itself will still function correctly and lookups will
41/// arbitrarily return one of the matching elements. However you should avoid
42/// doing this because it changes the runtime of hash table operations from
43/// `O(1)` to `O(k)` where `k` is the number of duplicate entries.
44///
45/// [`HashMap`]: super::HashMap
46/// [`HashSet`]: super::HashSet
47/// [`Hash`]: core::hash::Hash
48pub struct HashTable<T, A = Global>
49where
50 A: Allocator,
51{
52 pub(crate) raw: RawTable<T, A>,
53}
54
55impl<T> HashTable<T, Global> {
56 /// Creates an empty `HashTable`.
57 ///
58 /// The hash table is initially created with a capacity of 0, so it will not allocate until it
59 /// is first inserted into.
60 ///
61 /// # Examples
62 ///
63 /// ```
64 /// use hashbrown::HashTable;
65 /// let mut table: HashTable<&str> = HashTable::new();
66 /// assert_eq!(table.len(), 0);
67 /// assert_eq!(table.capacity(), 0);
68 /// ```
69 #[must_use]
70 pub const fn new() -> Self {
71 Self {
72 raw: RawTable::new(),
73 }
74 }
75
76 /// Creates an empty `HashTable` with the specified capacity.
77 ///
78 /// The hash table will be able to hold at least `capacity` elements without
79 /// reallocating. If `capacity` is 0, the hash table will not allocate.
80 ///
81 /// # Examples
82 ///
83 /// ```
84 /// use hashbrown::HashTable;
85 /// let mut table: HashTable<&str> = HashTable::with_capacity(10);
86 /// assert_eq!(table.len(), 0);
87 /// assert!(table.capacity() >= 10);
88 /// ```
89 #[must_use]
90 pub fn with_capacity(capacity: usize) -> Self {
91 Self {
92 raw: RawTable::with_capacity(capacity),
93 }
94 }
95}
96
97impl<T, A> HashTable<T, A>
98where
99 A: Allocator,
100{
101 /// Creates an empty `HashTable` using the given allocator.
102 ///
103 /// The hash table is initially created with a capacity of 0, so it will not allocate until it
104 /// is first inserted into.
105 ///
106 /// # Examples
107 ///
108 /// ```
109 /// # #[cfg(feature = "nightly")]
110 /// # fn test() {
111 /// use bumpalo::Bump;
112 /// use hashbrown::{HashTable, DefaultHashBuilder};
113 /// use std::hash::BuildHasher;
114 ///
115 /// let bump = Bump::new();
116 /// let mut table = HashTable::new_in(&bump);
117 /// let hasher = DefaultHashBuilder::default();
118 /// let hasher = |val: &_| hasher.hash_one(val);
119 ///
120 /// // The created HashTable holds none elements
121 /// assert_eq!(table.len(), 0);
122 ///
123 /// // The created HashTable also doesn't allocate memory
124 /// assert_eq!(table.capacity(), 0);
125 ///
126 /// // Now we insert element inside created HashTable
127 /// table.insert_unique(hasher(&"One"), "One", hasher);
128 /// // We can see that the HashTable holds 1 element
129 /// assert_eq!(table.len(), 1);
130 /// // And it also allocates some capacity
131 /// assert!(table.capacity() > 1);
132 /// # }
133 /// # fn main() {
134 /// # #[cfg(feature = "nightly")]
135 /// # test()
136 /// # }
137 /// ```
138 #[must_use]
139 pub const fn new_in(alloc: A) -> Self {
140 Self {
141 raw: RawTable::new_in(alloc),
142 }
143 }
144
145 /// Creates an empty `HashTable` with the specified capacity using the given allocator.
146 ///
147 /// The hash table will be able to hold at least `capacity` elements without
148 /// reallocating. If `capacity` is 0, the hash table will not allocate.
149 ///
150 /// # Examples
151 ///
152 /// ```
153 /// # #[cfg(feature = "nightly")]
154 /// # fn test() {
155 /// use bumpalo::Bump;
156 /// use hashbrown::{HashTable, DefaultHashBuilder};
157 /// use std::hash::BuildHasher;
158 ///
159 /// let bump = Bump::new();
160 /// let mut table = HashTable::with_capacity_in(5, &bump);
161 /// let hasher = DefaultHashBuilder::default();
162 /// let hasher = |val: &_| hasher.hash_one(val);
163 ///
164 /// // The created HashTable holds none elements
165 /// assert_eq!(table.len(), 0);
166 /// // But it can hold at least 5 elements without reallocating
167 /// let empty_map_capacity = table.capacity();
168 /// assert!(empty_map_capacity >= 5);
169 ///
170 /// // Now we insert some 5 elements inside created HashTable
171 /// table.insert_unique(hasher(&"One"), "One", hasher);
172 /// table.insert_unique(hasher(&"Two"), "Two", hasher);
173 /// table.insert_unique(hasher(&"Three"), "Three", hasher);
174 /// table.insert_unique(hasher(&"Four"), "Four", hasher);
175 /// table.insert_unique(hasher(&"Five"), "Five", hasher);
176 ///
177 /// // We can see that the HashTable holds 5 elements
178 /// assert_eq!(table.len(), 5);
179 /// // But its capacity isn't changed
180 /// assert_eq!(table.capacity(), empty_map_capacity)
181 /// # }
182 /// # fn main() {
183 /// # #[cfg(feature = "nightly")]
184 /// # test()
185 /// # }
186 /// ```
187 #[must_use]
188 pub fn with_capacity_in(capacity: usize, alloc: A) -> Self {
189 Self {
190 raw: RawTable::with_capacity_in(capacity, alloc),
191 }
192 }
193
194 /// Returns a reference to the underlying allocator.
195 pub fn allocator(&self) -> &A {
196 self.raw.allocator()
197 }
198
199 /// Returns a reference to an entry in the table with the given hash and
200 /// which satisfies the equality function passed.
201 ///
202 /// This method will call `eq` for all entries with the given hash, but may
203 /// also call it for entries with a different hash. `eq` should only return
204 /// true for the desired entry, at which point the search is stopped.
205 ///
206 /// # Examples
207 ///
208 /// ```
209 /// # #[cfg(feature = "nightly")]
210 /// # fn test() {
211 /// use hashbrown::{HashTable, DefaultHashBuilder};
212 /// use std::hash::BuildHasher;
213 ///
214 /// let mut table = HashTable::new();
215 /// let hasher = DefaultHashBuilder::default();
216 /// let hasher = |val: &_| hasher.hash_one(val);
217 /// table.insert_unique(hasher(&1), 1, hasher);
218 /// table.insert_unique(hasher(&2), 2, hasher);
219 /// table.insert_unique(hasher(&3), 3, hasher);
220 /// assert_eq!(table.find(hasher(&2), |&val| val == 2), Some(&2));
221 /// assert_eq!(table.find(hasher(&4), |&val| val == 4), None);
222 /// # }
223 /// # fn main() {
224 /// # #[cfg(feature = "nightly")]
225 /// # test()
226 /// # }
227 /// ```
228 pub fn find(&self, hash: u64, eq: impl FnMut(&T) -> bool) -> Option<&T> {
229 self.raw.get(hash, eq)
230 }
231
232 /// Returns a mutable reference to an entry in the table with the given hash
233 /// and which satisfies the equality function passed.
234 ///
235 /// This method will call `eq` for all entries with the given hash, but may
236 /// also call it for entries with a different hash. `eq` should only return
237 /// true for the desired entry, at which point the search is stopped.
238 ///
239 /// When mutating an entry, you should ensure that it still retains the same
240 /// hash value as when it was inserted, otherwise lookups of that entry may
241 /// fail to find it.
242 ///
243 /// # Examples
244 ///
245 /// ```
246 /// # #[cfg(feature = "nightly")]
247 /// # fn test() {
248 /// use hashbrown::{HashTable, DefaultHashBuilder};
249 /// use std::hash::BuildHasher;
250 ///
251 /// let mut table = HashTable::new();
252 /// let hasher = DefaultHashBuilder::default();
253 /// let hasher = |val: &_| hasher.hash_one(val);
254 /// table.insert_unique(hasher(&1), (1, "a"), |val| hasher(&val.0));
255 /// if let Some(val) = table.find_mut(hasher(&1), |val| val.0 == 1) {
256 /// val.1 = "b";
257 /// }
258 /// assert_eq!(table.find(hasher(&1), |val| val.0 == 1), Some(&(1, "b")));
259 /// assert_eq!(table.find(hasher(&2), |val| val.0 == 2), None);
260 /// # }
261 /// # fn main() {
262 /// # #[cfg(feature = "nightly")]
263 /// # test()
264 /// # }
265 /// ```
266 pub fn find_mut(&mut self, hash: u64, eq: impl FnMut(&T) -> bool) -> Option<&mut T> {
267 self.raw.get_mut(hash, eq)
268 }
269
270 /// Returns an `OccupiedEntry` for an entry in the table with the given hash
271 /// and which satisfies the equality function passed.
272 ///
273 /// This can be used to remove the entry from the table. Call
274 /// [`HashTable::entry`] instead if you wish to insert an entry if the
275 /// lookup fails.
276 ///
277 /// This method will call `eq` for all entries with the given hash, but may
278 /// also call it for entries with a different hash. `eq` should only return
279 /// true for the desired entry, at which point the search is stopped.
280 ///
281 /// # Examples
282 ///
283 /// ```
284 /// # #[cfg(feature = "nightly")]
285 /// # fn test() {
286 /// use hashbrown::{HashTable, DefaultHashBuilder};
287 /// use std::hash::BuildHasher;
288 ///
289 /// let mut table = HashTable::new();
290 /// let hasher = DefaultHashBuilder::default();
291 /// let hasher = |val: &_| hasher.hash_one(val);
292 /// table.insert_unique(hasher(&1), (1, "a"), |val| hasher(&val.0));
293 /// if let Ok(entry) = table.find_entry(hasher(&1), |val| val.0 == 1) {
294 /// entry.remove();
295 /// }
296 /// assert_eq!(table.find(hasher(&1), |val| val.0 == 1), None);
297 /// # }
298 /// # fn main() {
299 /// # #[cfg(feature = "nightly")]
300 /// # test()
301 /// # }
302 /// ```
303 #[cfg_attr(feature = "inline-more", inline)]
304 pub fn find_entry(
305 &mut self,
306 hash: u64,
307 eq: impl FnMut(&T) -> bool,
308 ) -> Result<OccupiedEntry<'_, T, A>, AbsentEntry<'_, T, A>> {
309 match self.raw.find(hash, eq) {
310 Some(bucket) => Ok(OccupiedEntry {
311 bucket,
312 table: self,
313 }),
314 None => Err(AbsentEntry { table: self }),
315 }
316 }
317
318 /// Returns the bucket index in the table for an entry with the given hash
319 /// and which satisfies the equality function passed.
320 ///
321 /// This can be used to store a borrow-free "reference" to the entry, later using
322 /// [`get_bucket`][Self::get_bucket], [`get_bucket_mut`][Self::get_bucket_mut], or
323 /// [`get_bucket_entry`][Self::get_bucket_entry] to access it again without hash probing.
324 ///
325 /// The index is only meaningful as long as the table is not resized and no entries are added
326 /// or removed. After such changes, it may end up pointing to a different entry or none at all.
327 ///
328 /// # Examples
329 ///
330 /// ```
331 /// # #[cfg(feature = "nightly")]
332 /// # fn test() {
333 /// use hashbrown::{HashTable, DefaultHashBuilder};
334 /// use std::hash::BuildHasher;
335 ///
336 /// let mut table = HashTable::new();
337 /// let hasher = DefaultHashBuilder::default();
338 /// let hasher = |val: &_| hasher.hash_one(val);
339 /// table.insert_unique(hasher(&1), (1, 1), |val| hasher(&val.0));
340 /// table.insert_unique(hasher(&2), (2, 2), |val| hasher(&val.0));
341 /// table.insert_unique(hasher(&3), (3, 3), |val| hasher(&val.0));
342 ///
343 /// let index = table.find_bucket_index(hasher(&2), |val| val.0 == 2).unwrap();
344 /// assert_eq!(table.get_bucket(index), Some(&(2, 2)));
345 ///
346 /// // Mutation would invalidate any normal reference
347 /// for (_key, value) in &mut table {
348 /// *value *= 11;
349 /// }
350 ///
351 /// // The index still reaches the same key with the updated value
352 /// assert_eq!(table.get_bucket(index), Some(&(2, 22)));
353 /// # }
354 /// # fn main() {
355 /// # #[cfg(feature = "nightly")]
356 /// # test()
357 /// # }
358 /// ```
359 #[cfg_attr(feature = "inline-more", inline)]
360 pub fn find_bucket_index(&self, hash: u64, eq: impl FnMut(&T) -> bool) -> Option<usize> {
361 match self.raw.find(hash, eq) {
362 Some(bucket) => Some(unsafe { self.raw.bucket_index(&bucket) }),
363 None => None,
364 }
365 }
366
367 /// Returns an `Entry` for an entry in the table with the given hash
368 /// and which satisfies the equality function passed.
369 ///
370 /// This can be used to remove the entry from the table, or insert a new
371 /// entry with the given hash if one doesn't already exist.
372 ///
373 /// This method will call `eq` for all entries with the given hash, but may
374 /// also call it for entries with a different hash. `eq` should only return
375 /// true for the desired entry, at which point the search is stopped.
376 ///
377 /// This method may grow the table in preparation for an insertion. Call
378 /// [`HashTable::find_entry`] if this is undesirable.
379 ///
380 /// `hasher` is called if entries need to be moved or copied to a new table.
381 /// This must return the same hash value that each entry was inserted with.
382 ///
383 /// # Examples
384 ///
385 /// ```
386 /// # #[cfg(feature = "nightly")]
387 /// # fn test() {
388 /// use hashbrown::hash_table::Entry;
389 /// use hashbrown::{HashTable, DefaultHashBuilder};
390 /// use std::hash::BuildHasher;
391 ///
392 /// let mut table = HashTable::new();
393 /// let hasher = DefaultHashBuilder::default();
394 /// let hasher = |val: &_| hasher.hash_one(val);
395 /// table.insert_unique(hasher(&1), (1, "a"), |val| hasher(&val.0));
396 /// if let Entry::Occupied(entry) = table.entry(hasher(&1), |val| val.0 == 1, |val| hasher(&val.0))
397 /// {
398 /// entry.remove();
399 /// }
400 /// if let Entry::Vacant(entry) = table.entry(hasher(&2), |val| val.0 == 2, |val| hasher(&val.0)) {
401 /// entry.insert((2, "b"));
402 /// }
403 /// assert_eq!(table.find(hasher(&1), |val| val.0 == 1), None);
404 /// assert_eq!(table.find(hasher(&2), |val| val.0 == 2), Some(&(2, "b")));
405 /// # }
406 /// # fn main() {
407 /// # #[cfg(feature = "nightly")]
408 /// # test()
409 /// # }
410 /// ```
411 #[cfg_attr(feature = "inline-more", inline)]
412 pub fn entry(
413 &mut self,
414 hash: u64,
415 eq: impl FnMut(&T) -> bool,
416 hasher: impl Fn(&T) -> u64,
417 ) -> Entry<'_, T, A> {
418 match self.raw.find_or_find_insert_index(hash, eq, hasher) {
419 Ok(bucket) => Entry::Occupied(OccupiedEntry {
420 bucket,
421 table: self,
422 }),
423 Err(insert_index) => Entry::Vacant(VacantEntry {
424 tag: Tag::full(hash),
425 index: insert_index,
426 table: self,
427 }),
428 }
429 }
430
431 /// Returns an `OccupiedEntry` for the given bucket index in the table,
432 /// or `AbsentEntry` if it is unoccupied or out of bounds.
433 ///
434 /// # Examples
435 ///
436 /// ```
437 /// # #[cfg(feature = "nightly")]
438 /// # fn test() {
439 /// use hashbrown::{HashTable, DefaultHashBuilder};
440 /// use std::hash::BuildHasher;
441 ///
442 /// let mut table = HashTable::new();
443 /// let hasher = DefaultHashBuilder::default();
444 /// let hasher = |val: &_| hasher.hash_one(val);
445 /// table.insert_unique(hasher(&1), (1, 'a'), |val| hasher(&val.0));
446 /// table.insert_unique(hasher(&2), (2, 'b'), |val| hasher(&val.0));
447 /// table.insert_unique(hasher(&3), (3, 'c'), |val| hasher(&val.0));
448 ///
449 /// let index = table.find_bucket_index(hasher(&2), |val| val.0 == 2).unwrap();
450 ///
451 /// assert!(table.get_bucket_entry(usize::MAX).is_err());
452 ///
453 /// let occupied_entry = table.get_bucket_entry(index).unwrap();
454 /// assert_eq!(occupied_entry.get(), &(2, 'b'));
455 /// assert_eq!(occupied_entry.remove().0, (2, 'b'));
456 ///
457 /// assert!(table.find(hasher(&2), |val| val.0 == 2).is_none());
458 /// # }
459 /// # fn main() {
460 /// # #[cfg(feature = "nightly")]
461 /// # test()
462 /// # }
463 /// ```
464 #[inline]
465 pub fn get_bucket_entry(
466 &mut self,
467 index: usize,
468 ) -> Result<OccupiedEntry<'_, T, A>, AbsentEntry<'_, T, A>> {
469 match self.raw.checked_bucket(index) {
470 Some(bucket) => Ok(OccupiedEntry {
471 bucket,
472 table: self,
473 }),
474 None => Err(AbsentEntry { table: self }),
475 }
476 }
477
478 /// Returns an `OccupiedEntry` for the given bucket index in the table,
479 /// without checking whether the index is in-bounds or occupied.
480 ///
481 /// For a safe alternative, see [`get_bucket_entry`](Self::get_bucket_entry).
482 ///
483 /// # Safety
484 ///
485 /// It is *[undefined behavior]* to call this method with an index that is
486 /// out-of-bounds or unoccupied, even if the resulting entry is not used.
487 ///
488 /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
489 ///
490 /// # Examples
491 ///
492 /// ```
493 /// # #[cfg(feature = "nightly")]
494 /// # fn test() {
495 /// use hashbrown::{HashTable, DefaultHashBuilder};
496 /// use std::hash::BuildHasher;
497 ///
498 /// let mut table = HashTable::new();
499 /// let hasher = DefaultHashBuilder::default();
500 /// let hasher = |val: &_| hasher.hash_one(val);
501 /// table.insert_unique(hasher(&1), (1, 'a'), |val| hasher(&val.0));
502 /// table.insert_unique(hasher(&2), (2, 'b'), |val| hasher(&val.0));
503 /// table.insert_unique(hasher(&3), (3, 'c'), |val| hasher(&val.0));
504 ///
505 /// let index = table.find_bucket_index(hasher(&2), |val| val.0 == 2).unwrap();
506 /// assert!(std::ptr::eq(
507 /// table.get_bucket_entry(index).unwrap().into_mut(),
508 /// unsafe { table.get_bucket_entry_unchecked(index).into_mut() },
509 /// ));
510 /// # }
511 /// # fn main() {
512 /// # #[cfg(feature = "nightly")]
513 /// # test()
514 /// # }
515 /// ```
516 #[inline]
517 pub unsafe fn get_bucket_entry_unchecked(&mut self, index: usize) -> OccupiedEntry<'_, T, A> {
518 OccupiedEntry {
519 bucket: unsafe { self.raw.bucket(index) },
520 table: self,
521 }
522 }
523
524 /// Gets a reference to an entry in the table at the given bucket index,
525 /// or `None` if it is unoccupied or out of bounds.
526 ///
527 /// # Examples
528 ///
529 /// ```
530 /// # #[cfg(feature = "nightly")]
531 /// # fn test() {
532 /// use hashbrown::{HashTable, DefaultHashBuilder};
533 /// use std::hash::BuildHasher;
534 ///
535 /// let mut table = HashTable::new();
536 /// let hasher = DefaultHashBuilder::default();
537 /// let hasher = |val: &_| hasher.hash_one(val);
538 /// table.insert_unique(hasher(&1), (1, 'a'), |val| hasher(&val.0));
539 /// table.insert_unique(hasher(&2), (2, 'b'), |val| hasher(&val.0));
540 /// table.insert_unique(hasher(&3), (3, 'c'), |val| hasher(&val.0));
541 ///
542 /// let index = table.find_bucket_index(hasher(&2), |val| val.0 == 2).unwrap();
543 /// assert_eq!(table.get_bucket(index), Some(&(2, 'b')));
544 /// # }
545 /// # fn main() {
546 /// # #[cfg(feature = "nightly")]
547 /// # test()
548 /// # }
549 /// ```
550 #[inline]
551 pub fn get_bucket(&self, index: usize) -> Option<&T> {
552 self.raw.get_bucket(index)
553 }
554
555 /// Gets a reference to an entry in the table at the given bucket index,
556 /// without checking whether the index is in-bounds or occupied.
557 ///
558 /// For a safe alternative, see [`get_bucket`](Self::get_bucket).
559 ///
560 /// # Safety
561 ///
562 /// It is *[undefined behavior]* to call this method with an index that is
563 /// out-of-bounds or unoccupied, even if the resulting reference is not used.
564 ///
565 /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
566 ///
567 /// # Examples
568 ///
569 /// ```
570 /// # #[cfg(feature = "nightly")]
571 /// # fn test() {
572 /// use hashbrown::{HashTable, DefaultHashBuilder};
573 /// use std::hash::BuildHasher;
574 ///
575 /// let mut table = HashTable::new();
576 /// let hasher = DefaultHashBuilder::default();
577 /// let hasher = |val: &_| hasher.hash_one(val);
578 /// table.insert_unique(hasher(&1), (1, 'a'), |val| hasher(&val.0));
579 /// table.insert_unique(hasher(&2), (2, 'b'), |val| hasher(&val.0));
580 /// table.insert_unique(hasher(&3), (3, 'c'), |val| hasher(&val.0));
581 ///
582 /// let index = table.find_bucket_index(hasher(&2), |val| val.0 == 2).unwrap();
583 /// assert!(std::ptr::eq(
584 /// table.get_bucket(index).unwrap(),
585 /// unsafe { table.get_bucket_unchecked(index) },
586 /// ));
587 /// # }
588 /// # fn main() {
589 /// # #[cfg(feature = "nightly")]
590 /// # test()
591 /// # }
592 /// ```
593 #[inline]
594 pub unsafe fn get_bucket_unchecked(&self, index: usize) -> &T {
595 unsafe { self.raw.bucket(index).as_ref() }
596 }
597
598 /// Gets a mutable reference to an entry in the table at the given bucket index,
599 /// or `None` if it is unoccupied or out of bounds.
600 ///
601 /// # Examples
602 ///
603 /// ```
604 /// # #[cfg(feature = "nightly")]
605 /// # fn test() {
606 /// use hashbrown::{HashTable, DefaultHashBuilder};
607 /// use std::hash::BuildHasher;
608 ///
609 /// let mut table = HashTable::new();
610 /// let hasher = DefaultHashBuilder::default();
611 /// let hasher = |val: &_| hasher.hash_one(val);
612 /// table.insert_unique(hasher(&1), (1, 'a'), |val| hasher(&val.0));
613 /// table.insert_unique(hasher(&2), (2, 'b'), |val| hasher(&val.0));
614 /// table.insert_unique(hasher(&3), (3, 'c'), |val| hasher(&val.0));
615 ///
616 /// let index = table.find_bucket_index(hasher(&2), |val| val.0 == 2).unwrap();
617 /// assert_eq!(table.get_bucket(index), Some(&(2, 'b')));
618 /// if let Some((_key, value)) = table.get_bucket_mut(index) {
619 /// *value = 'B';
620 /// }
621 /// assert_eq!(table.get_bucket(index), Some(&(2, 'B')));
622 /// # }
623 /// # fn main() {
624 /// # #[cfg(feature = "nightly")]
625 /// # test()
626 /// # }
627 /// ```
628 #[inline]
629 pub fn get_bucket_mut(&mut self, index: usize) -> Option<&mut T> {
630 self.raw.get_bucket_mut(index)
631 }
632
633 /// Gets a mutable reference to an entry in the table at the given bucket index,
634 /// without checking whether the index is in-bounds or occupied.
635 ///
636 /// For a safe alternative, see [`get_bucket_mut`](Self::get_bucket_mut).
637 ///
638 /// # Safety
639 ///
640 /// It is *[undefined behavior]* to call this method with an index that is
641 /// out-of-bounds or unoccupied, even if the resulting reference is not used.
642 ///
643 /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
644 ///
645 /// # Examples
646 ///
647 /// ```
648 /// # #[cfg(feature = "nightly")]
649 /// # fn test() {
650 /// use hashbrown::{HashTable, DefaultHashBuilder};
651 /// use std::hash::BuildHasher;
652 ///
653 /// let mut table = HashTable::new();
654 /// let hasher = DefaultHashBuilder::default();
655 /// let hasher = |val: &_| hasher.hash_one(val);
656 /// table.insert_unique(hasher(&1), (1, 'a'), |val| hasher(&val.0));
657 /// table.insert_unique(hasher(&2), (2, 'b'), |val| hasher(&val.0));
658 /// table.insert_unique(hasher(&3), (3, 'c'), |val| hasher(&val.0));
659 ///
660 /// let index = table.find_bucket_index(hasher(&2), |val| val.0 == 2).unwrap();
661 /// assert!(std::ptr::eq(
662 /// table.get_bucket_mut(index).unwrap(),
663 /// unsafe { table.get_bucket_unchecked_mut(index) },
664 /// ));
665 /// # }
666 /// # fn main() {
667 /// # #[cfg(feature = "nightly")]
668 /// # test()
669 /// # }
670 /// ```
671 #[inline]
672 pub unsafe fn get_bucket_unchecked_mut(&mut self, index: usize) -> &mut T {
673 unsafe { self.raw.bucket(index).as_mut() }
674 }
675
676 /// Inserts an element into the `HashTable` with the given hash value, but
677 /// without checking whether an equivalent element already exists within the
678 /// table.
679 ///
680 /// `hasher` is called if entries need to be moved or copied to a new table.
681 /// This must return the same hash value that each entry was inserted with.
682 ///
683 /// # Examples
684 ///
685 /// ```
686 /// # #[cfg(feature = "nightly")]
687 /// # fn test() {
688 /// use hashbrown::{HashTable, DefaultHashBuilder};
689 /// use std::hash::BuildHasher;
690 ///
691 /// let mut v = HashTable::new();
692 /// let hasher = DefaultHashBuilder::default();
693 /// let hasher = |val: &_| hasher.hash_one(val);
694 /// v.insert_unique(hasher(&1), 1, hasher);
695 /// # }
696 /// # fn main() {
697 /// # #[cfg(feature = "nightly")]
698 /// # test()
699 /// # }
700 /// ```
701 pub fn insert_unique(
702 &mut self,
703 hash: u64,
704 value: T,
705 hasher: impl Fn(&T) -> u64,
706 ) -> OccupiedEntry<'_, T, A> {
707 let bucket = self.raw.insert(hash, value, hasher);
708 OccupiedEntry {
709 bucket,
710 table: self,
711 }
712 }
713
714 /// Clears the table, removing all values.
715 ///
716 /// # Examples
717 ///
718 /// ```
719 /// # #[cfg(feature = "nightly")]
720 /// # fn test() {
721 /// use hashbrown::{HashTable, DefaultHashBuilder};
722 /// use std::hash::BuildHasher;
723 ///
724 /// let mut v = HashTable::new();
725 /// let hasher = DefaultHashBuilder::default();
726 /// let hasher = |val: &_| hasher.hash_one(val);
727 /// v.insert_unique(hasher(&1), 1, hasher);
728 /// v.clear();
729 /// assert!(v.is_empty());
730 /// # }
731 /// # fn main() {
732 /// # #[cfg(feature = "nightly")]
733 /// # test()
734 /// # }
735 /// ```
736 pub fn clear(&mut self) {
737 self.raw.clear();
738 }
739
740 /// Shrinks the capacity of the table as much as possible. It will drop
741 /// down as much as possible while maintaining the internal rules
742 /// and possibly leaving some space in accordance with the resize policy.
743 ///
744 /// `hasher` is called if entries need to be moved or copied to a new table.
745 /// This must return the same hash value that each entry was inserted with.
746 ///
747 /// # Examples
748 ///
749 /// ```
750 /// # #[cfg(feature = "nightly")]
751 /// # fn test() {
752 /// use hashbrown::{HashTable, DefaultHashBuilder};
753 /// use std::hash::BuildHasher;
754 ///
755 /// let mut table = HashTable::with_capacity(100);
756 /// let hasher = DefaultHashBuilder::default();
757 /// let hasher = |val: &_| hasher.hash_one(val);
758 /// table.insert_unique(hasher(&1), 1, hasher);
759 /// table.insert_unique(hasher(&2), 2, hasher);
760 /// assert!(table.capacity() >= 100);
761 /// table.shrink_to_fit(hasher);
762 /// assert!(table.capacity() >= 2);
763 /// # }
764 /// # fn main() {
765 /// # #[cfg(feature = "nightly")]
766 /// # test()
767 /// # }
768 /// ```
769 pub fn shrink_to_fit(&mut self, hasher: impl Fn(&T) -> u64) {
770 self.raw.shrink_to(self.len(), hasher);
771 }
772
773 /// Shrinks the capacity of the table with a lower limit. It will drop
774 /// down no lower than the supplied limit while maintaining the internal rules
775 /// and possibly leaving some space in accordance with the resize policy.
776 ///
777 /// `hasher` is called if entries need to be moved or copied to a new table.
778 /// This must return the same hash value that each entry was inserted with.
779 ///
780 /// Panics if the current capacity is smaller than the supplied
781 /// minimum capacity.
782 ///
783 /// # Examples
784 ///
785 /// ```
786 /// # #[cfg(feature = "nightly")]
787 /// # fn test() {
788 /// use hashbrown::{HashTable, DefaultHashBuilder};
789 /// use std::hash::BuildHasher;
790 ///
791 /// let mut table = HashTable::with_capacity(100);
792 /// let hasher = DefaultHashBuilder::default();
793 /// let hasher = |val: &_| hasher.hash_one(val);
794 /// table.insert_unique(hasher(&1), 1, hasher);
795 /// table.insert_unique(hasher(&2), 2, hasher);
796 /// assert!(table.capacity() >= 100);
797 /// table.shrink_to(10, hasher);
798 /// assert!(table.capacity() >= 10);
799 /// table.shrink_to(0, hasher);
800 /// assert!(table.capacity() >= 2);
801 /// # }
802 /// # fn main() {
803 /// # #[cfg(feature = "nightly")]
804 /// # test()
805 /// # }
806 /// ```
807 pub fn shrink_to(&mut self, min_capacity: usize, hasher: impl Fn(&T) -> u64) {
808 self.raw.shrink_to(min_capacity, hasher);
809 }
810
811 /// Reserves capacity for at least `additional` more elements to be inserted
812 /// in the `HashTable`. The collection may reserve more space to avoid
813 /// frequent reallocations.
814 ///
815 /// `hasher` is called if entries need to be moved or copied to a new table.
816 /// This must return the same hash value that each entry was inserted with.
817 ///
818 /// # Panics
819 ///
820 /// Panics if the new capacity exceeds [`isize::MAX`] bytes and [`abort`] the program
821 /// in case of allocation error. Use [`try_reserve`](HashTable::try_reserve) instead
822 /// if you want to handle memory allocation failure.
823 ///
824 /// [`abort`]: stdalloc::alloc::handle_alloc_error
825 ///
826 /// # Examples
827 ///
828 /// ```
829 /// # #[cfg(feature = "nightly")]
830 /// # fn test() {
831 /// use hashbrown::{HashTable, DefaultHashBuilder};
832 /// use std::hash::BuildHasher;
833 ///
834 /// let mut table: HashTable<i32> = HashTable::new();
835 /// let hasher = DefaultHashBuilder::default();
836 /// let hasher = |val: &_| hasher.hash_one(val);
837 /// table.reserve(10, hasher);
838 /// assert!(table.capacity() >= 10);
839 /// # }
840 /// # fn main() {
841 /// # #[cfg(feature = "nightly")]
842 /// # test()
843 /// # }
844 /// ```
845 pub fn reserve(&mut self, additional: usize, hasher: impl Fn(&T) -> u64) {
846 self.raw.reserve(additional, hasher);
847 }
848
849 /// Tries to reserve capacity for at least `additional` more elements to be inserted
850 /// in the given `HashTable`. The collection may reserve more space to avoid
851 /// frequent reallocations.
852 ///
853 /// `hasher` is called if entries need to be moved or copied to a new table.
854 /// This must return the same hash value that each entry was inserted with.
855 ///
856 /// # Errors
857 ///
858 /// If the capacity overflows, or the allocator reports a failure, then an error
859 /// is returned.
860 ///
861 /// # Examples
862 ///
863 /// ```
864 /// # #[cfg(feature = "nightly")]
865 /// # fn test() {
866 /// use hashbrown::{HashTable, DefaultHashBuilder};
867 /// use std::hash::BuildHasher;
868 ///
869 /// let mut table: HashTable<i32> = HashTable::new();
870 /// let hasher = DefaultHashBuilder::default();
871 /// let hasher = |val: &_| hasher.hash_one(val);
872 /// table
873 /// .try_reserve(10, hasher)
874 /// .expect("why is the test harness OOMing on 10 bytes?");
875 /// # }
876 /// # fn main() {
877 /// # #[cfg(feature = "nightly")]
878 /// # test()
879 /// # }
880 /// ```
881 pub fn try_reserve(
882 &mut self,
883 additional: usize,
884 hasher: impl Fn(&T) -> u64,
885 ) -> Result<(), TryReserveError> {
886 self.raw.try_reserve(additional, hasher)
887 }
888
889 /// Returns the raw number of buckets allocated in the table.
890 ///
891 /// This is an upper bound on any methods that take or return a bucket index,
892 /// as opposed to the usable [`capacity`](Self::capacity) for entries which is
893 /// reduced by an unspecified load factor.
894 ///
895 /// # Examples
896 ///
897 /// ```
898 /// # #[cfg(feature = "nightly")]
899 /// # fn test() {
900 /// use hashbrown::{HashTable, DefaultHashBuilder};
901 /// use std::hash::BuildHasher;
902 ///
903 /// let mut table = HashTable::new();
904 /// let hasher = DefaultHashBuilder::default();
905 /// let hasher = |val: &_| hasher.hash_one(val);
906 /// table.insert_unique(hasher(&1), (1, 'a'), |val| hasher(&val.0));
907 /// table.insert_unique(hasher(&2), (2, 'b'), |val| hasher(&val.0));
908 /// table.insert_unique(hasher(&3), (3, 'c'), |val| hasher(&val.0));
909 ///
910 /// // Each entry is available at some index in the bucket range.
911 /// let count = (0..table.num_buckets())
912 /// .filter_map(|i| table.get_bucket(i))
913 /// .count();
914 /// assert_eq!(count, 3);
915 ///
916 /// assert_eq!(table.get_bucket(table.num_buckets()), None);
917 /// # }
918 /// # fn main() {
919 /// # #[cfg(feature = "nightly")]
920 /// # test()
921 /// # }
922 /// ```
923 pub fn num_buckets(&self) -> usize {
924 self.raw.num_buckets()
925 }
926
927 /// Returns the number of elements the table can hold without reallocating.
928 ///
929 /// # Examples
930 ///
931 /// ```
932 /// use hashbrown::HashTable;
933 /// let table: HashTable<i32> = HashTable::with_capacity(100);
934 /// assert!(table.capacity() >= 100);
935 /// ```
936 pub fn capacity(&self) -> usize {
937 self.raw.capacity()
938 }
939
940 /// Returns the number of elements in the table.
941 ///
942 /// # Examples
943 ///
944 /// ```
945 /// # #[cfg(feature = "nightly")]
946 /// # fn test() {
947 /// use hashbrown::{HashTable, DefaultHashBuilder};
948 /// use std::hash::BuildHasher;
949 ///
950 /// let hasher = DefaultHashBuilder::default();
951 /// let hasher = |val: &_| hasher.hash_one(val);
952 /// let mut v = HashTable::new();
953 /// assert_eq!(v.len(), 0);
954 /// v.insert_unique(hasher(&1), 1, hasher);
955 /// assert_eq!(v.len(), 1);
956 /// # }
957 /// # fn main() {
958 /// # #[cfg(feature = "nightly")]
959 /// # test()
960 /// # }
961 /// ```
962 pub fn len(&self) -> usize {
963 self.raw.len()
964 }
965
966 /// Returns `true` if the set contains no elements.
967 ///
968 /// # Examples
969 ///
970 /// ```
971 /// # #[cfg(feature = "nightly")]
972 /// # fn test() {
973 /// use hashbrown::{HashTable, DefaultHashBuilder};
974 /// use std::hash::BuildHasher;
975 ///
976 /// let hasher = DefaultHashBuilder::default();
977 /// let hasher = |val: &_| hasher.hash_one(val);
978 /// let mut v = HashTable::new();
979 /// assert!(v.is_empty());
980 /// v.insert_unique(hasher(&1), 1, hasher);
981 /// assert!(!v.is_empty());
982 /// # }
983 /// # fn main() {
984 /// # #[cfg(feature = "nightly")]
985 /// # test()
986 /// # }
987 /// ```
988 pub fn is_empty(&self) -> bool {
989 self.raw.is_empty()
990 }
991
992 /// An iterator visiting all elements in arbitrary order.
993 /// The iterator element type is `&'a T`.
994 ///
995 /// # Examples
996 ///
997 /// ```
998 /// # #[cfg(feature = "nightly")]
999 /// # fn test() {
1000 /// use hashbrown::{HashTable, DefaultHashBuilder};
1001 /// use std::hash::BuildHasher;
1002 ///
1003 /// let mut table = HashTable::new();
1004 /// let hasher = DefaultHashBuilder::default();
1005 /// let hasher = |val: &_| hasher.hash_one(val);
1006 /// table.insert_unique(hasher(&"a"), "a", hasher);
1007 /// table.insert_unique(hasher(&"b"), "b", hasher);
1008 ///
1009 /// // Will print in an arbitrary order.
1010 /// for x in table.iter() {
1011 /// println!("{}", x);
1012 /// }
1013 /// # }
1014 /// # fn main() {
1015 /// # #[cfg(feature = "nightly")]
1016 /// # test()
1017 /// # }
1018 /// ```
1019 pub fn iter(&self) -> Iter<'_, T> {
1020 Iter {
1021 inner: unsafe { self.raw.iter() },
1022 marker: PhantomData,
1023 }
1024 }
1025
1026 /// An iterator visiting all elements in arbitrary order,
1027 /// with mutable references to the elements.
1028 /// The iterator element type is `&'a mut T`.
1029 ///
1030 /// # Examples
1031 ///
1032 /// ```
1033 /// # #[cfg(feature = "nightly")]
1034 /// # fn test() {
1035 /// use hashbrown::{HashTable, DefaultHashBuilder};
1036 /// use std::hash::BuildHasher;
1037 ///
1038 /// let mut table = HashTable::new();
1039 /// let hasher = DefaultHashBuilder::default();
1040 /// let hasher = |val: &_| hasher.hash_one(val);
1041 /// table.insert_unique(hasher(&1), 1, hasher);
1042 /// table.insert_unique(hasher(&2), 2, hasher);
1043 /// table.insert_unique(hasher(&3), 3, hasher);
1044 ///
1045 /// // Update all values
1046 /// for val in table.iter_mut() {
1047 /// *val *= 2;
1048 /// }
1049 ///
1050 /// assert_eq!(table.len(), 3);
1051 /// let mut vec: Vec<i32> = Vec::new();
1052 ///
1053 /// for val in &table {
1054 /// println!("val: {}", val);
1055 /// vec.push(*val);
1056 /// }
1057 ///
1058 /// // The `Iter` iterator produces items in arbitrary order, so the
1059 /// // items must be sorted to test them against a sorted array.
1060 /// vec.sort_unstable();
1061 /// assert_eq!(vec, [2, 4, 6]);
1062 ///
1063 /// assert_eq!(table.len(), 3);
1064 /// # }
1065 /// # fn main() {
1066 /// # #[cfg(feature = "nightly")]
1067 /// # test()
1068 /// # }
1069 /// ```
1070 pub fn iter_mut(&mut self) -> IterMut<'_, T> {
1071 IterMut {
1072 inner: unsafe { self.raw.iter() },
1073 marker: PhantomData,
1074 }
1075 }
1076
1077 /// An iterator visiting all elements in arbitrary order,
1078 /// with pointers to the elements.
1079 /// The iterator element type is `NonNull<T>`.
1080 ///
1081 /// This iterator is intended for APIs where only part of the elements are
1082 /// mutable, with the remainder being immutable. In these cases, wrapping
1083 /// the ordinary mutable iterator is incorrect because all components of
1084 /// the element type will be [invariant]. A correct implementation will use
1085 /// an appropriate [`PhantomData`] marker to make the immutable parts
1086 /// [covariant] and the mutable parts invariant.
1087 ///
1088 /// [invariant]: https://doc.rust-lang.org/stable/reference/subtyping.html#r-subtyping.variance.invariant
1089 /// [covariant]: https://doc.rust-lang.org/stable/reference/subtyping.html#r-subtyping.variance.covariant
1090 ///
1091 /// See the documentation for [`UnsafeIter`] for more information on how
1092 /// to correctly use this.
1093 pub fn unsafe_iter(&mut self) -> UnsafeIter<'_, T> {
1094 UnsafeIter {
1095 inner: unsafe { self.raw.iter() },
1096 marker: PhantomData,
1097 }
1098 }
1099
1100 /// An iterator producing the `usize` indices of all occupied buckets.
1101 ///
1102 /// The order in which the iterator yields indices is unspecified
1103 /// and may change in the future.
1104 ///
1105 /// # Examples
1106 ///
1107 /// ```
1108 /// # #[cfg(feature = "nightly")]
1109 /// # fn test() {
1110 /// use hashbrown::{HashTable, DefaultHashBuilder};
1111 /// use std::hash::BuildHasher;
1112 ///
1113 /// let mut table = HashTable::new();
1114 /// let hasher = DefaultHashBuilder::default();
1115 /// let hasher = |val: &_| hasher.hash_one(val);
1116 /// table.insert_unique(hasher(&"a"), "a", hasher);
1117 /// table.insert_unique(hasher(&"b"), "b", hasher);
1118 ///
1119 /// // Will print in an arbitrary order.
1120 /// for index in table.iter_buckets() {
1121 /// println!("{index}: {}", table.get_bucket(index).unwrap());
1122 /// }
1123 /// # }
1124 /// # fn main() {
1125 /// # #[cfg(feature = "nightly")]
1126 /// # test()
1127 /// # }
1128 /// ```
1129 pub fn iter_buckets(&self) -> IterBuckets<'_, T> {
1130 IterBuckets {
1131 inner: unsafe { self.raw.full_buckets_indices() },
1132 marker: PhantomData,
1133 }
1134 }
1135
1136 /// An iterator visiting all elements which may match a hash.
1137 /// The iterator element type is `&'a T`.
1138 ///
1139 /// This iterator may return elements from the table that have a hash value
1140 /// different than the one provided. You should always validate the returned
1141 /// values before using them.
1142 ///
1143 /// # Examples
1144 ///
1145 /// ```
1146 /// # #[cfg(feature = "nightly")]
1147 /// # fn test() {
1148 /// use hashbrown::{HashTable, DefaultHashBuilder};
1149 /// use std::hash::BuildHasher;
1150 ///
1151 /// let mut table = HashTable::new();
1152 /// let hasher = DefaultHashBuilder::default();
1153 /// let hasher = |val: &_| hasher.hash_one(val);
1154 /// table.insert_unique(hasher(&"a"), "a", hasher);
1155 /// table.insert_unique(hasher(&"a"), "b", hasher);
1156 /// table.insert_unique(hasher(&"b"), "c", hasher);
1157 ///
1158 /// // Will print "a" and "b" (and possibly "c") in an arbitrary order.
1159 /// for x in table.iter_hash(hasher(&"a")) {
1160 /// println!("{}", x);
1161 /// }
1162 /// # }
1163 /// # fn main() {
1164 /// # #[cfg(feature = "nightly")]
1165 /// # test()
1166 /// # }
1167 /// ```
1168 pub fn iter_hash(&self, hash: u64) -> IterHash<'_, T> {
1169 IterHash {
1170 inner: unsafe { self.raw.iter_hash(hash) },
1171 marker: PhantomData,
1172 }
1173 }
1174
1175 /// A mutable iterator visiting all elements which may match a hash.
1176 /// The iterator element type is `&'a mut T`.
1177 ///
1178 /// This iterator may return elements from the table that have a hash value
1179 /// different than the one provided. You should always validate the returned
1180 /// values before using them.
1181 ///
1182 /// # Examples
1183 ///
1184 /// ```
1185 /// # #[cfg(feature = "nightly")]
1186 /// # fn test() {
1187 /// use hashbrown::{HashTable, DefaultHashBuilder};
1188 /// use std::hash::BuildHasher;
1189 ///
1190 /// let mut table = HashTable::new();
1191 /// let hasher = DefaultHashBuilder::default();
1192 /// let hasher = |val: &_| hasher.hash_one(val);
1193 /// table.insert_unique(hasher(&1), 2, hasher);
1194 /// table.insert_unique(hasher(&1), 3, hasher);
1195 /// table.insert_unique(hasher(&2), 5, hasher);
1196 ///
1197 /// // Update matching values
1198 /// for val in table.iter_hash_mut(hasher(&1)) {
1199 /// *val *= 2;
1200 /// }
1201 ///
1202 /// assert_eq!(table.len(), 3);
1203 /// let mut vec: Vec<i32> = Vec::new();
1204 ///
1205 /// for val in &table {
1206 /// println!("val: {}", val);
1207 /// vec.push(*val);
1208 /// }
1209 ///
1210 /// // The values will contain 4 and 6 and may contain either 5 or 10.
1211 /// assert!(vec.contains(&4));
1212 /// assert!(vec.contains(&6));
1213 ///
1214 /// assert_eq!(table.len(), 3);
1215 /// # }
1216 /// # fn main() {
1217 /// # #[cfg(feature = "nightly")]
1218 /// # test()
1219 /// # }
1220 /// ```
1221 pub fn iter_hash_mut(&mut self, hash: u64) -> IterHashMut<'_, T> {
1222 IterHashMut {
1223 inner: unsafe { self.raw.iter_hash(hash) },
1224 marker: PhantomData,
1225 }
1226 }
1227
1228 /// An iterator producing the `usize` indices of all buckets which may match a hash.
1229 ///
1230 /// This iterator may return indices from the table that have a hash value
1231 /// different than the one provided. You should always validate the returned
1232 /// values before using them.
1233 ///
1234 /// The order in which the iterator yields indices is unspecified
1235 /// and may change in the future.
1236 ///
1237 /// # Examples
1238 ///
1239 /// ```
1240 /// # #[cfg(feature = "nightly")]
1241 /// # fn test() {
1242 /// use hashbrown::{HashTable, DefaultHashBuilder};
1243 /// use std::hash::BuildHasher;
1244 ///
1245 /// let mut table = HashTable::new();
1246 /// let hasher = DefaultHashBuilder::default();
1247 /// let hasher = |val: &_| hasher.hash_one(val);
1248 /// table.insert_unique(hasher(&"a"), "a", hasher);
1249 /// table.insert_unique(hasher(&"a"), "b", hasher);
1250 /// table.insert_unique(hasher(&"b"), "c", hasher);
1251 ///
1252 /// // Will print the indices with "a" and "b" (and possibly "c") in an arbitrary order.
1253 /// for index in table.iter_hash_buckets(hasher(&"a")) {
1254 /// println!("{index}: {}", table.get_bucket(index).unwrap());
1255 /// }
1256 /// # }
1257 /// # fn main() {
1258 /// # #[cfg(feature = "nightly")]
1259 /// # test()
1260 /// # }
1261 /// ```
1262 pub fn iter_hash_buckets(&self, hash: u64) -> IterHashBuckets<'_, T> {
1263 IterHashBuckets {
1264 inner: unsafe { self.raw.iter_hash_buckets(hash) },
1265 marker: PhantomData,
1266 }
1267 }
1268
1269 /// Retains only the elements specified by the predicate.
1270 ///
1271 /// In other words, remove all elements `e` such that `f(&e)` returns `false`.
1272 ///
1273 /// # Examples
1274 ///
1275 /// ```
1276 /// # #[cfg(feature = "nightly")]
1277 /// # fn test() {
1278 /// use hashbrown::{HashTable, DefaultHashBuilder};
1279 /// use std::hash::BuildHasher;
1280 ///
1281 /// let mut table = HashTable::new();
1282 /// let hasher = DefaultHashBuilder::default();
1283 /// let hasher = |val: &_| hasher.hash_one(val);
1284 /// for x in 1..=6 {
1285 /// table.insert_unique(hasher(&x), x, hasher);
1286 /// }
1287 /// table.retain(|&mut x| x % 2 == 0);
1288 /// assert_eq!(table.len(), 3);
1289 /// # }
1290 /// # fn main() {
1291 /// # #[cfg(feature = "nightly")]
1292 /// # test()
1293 /// # }
1294 /// ```
1295 pub fn retain(&mut self, mut f: impl FnMut(&mut T) -> bool) {
1296 // Here we only use `iter` as a temporary, preventing use-after-free
1297 unsafe {
1298 for item in self.raw.iter() {
1299 if !f(item.as_mut()) {
1300 self.raw.erase(item);
1301 }
1302 }
1303 }
1304 }
1305
1306 /// Clears the set, returning all elements in an iterator.
1307 ///
1308 /// # Examples
1309 ///
1310 /// ```
1311 /// # #[cfg(feature = "nightly")]
1312 /// # fn test() {
1313 /// use hashbrown::{HashTable, DefaultHashBuilder};
1314 /// use std::hash::BuildHasher;
1315 ///
1316 /// let mut table = HashTable::new();
1317 /// let hasher = DefaultHashBuilder::default();
1318 /// let hasher = |val: &_| hasher.hash_one(val);
1319 /// for x in 1..=3 {
1320 /// table.insert_unique(hasher(&x), x, hasher);
1321 /// }
1322 /// assert!(!table.is_empty());
1323 ///
1324 /// // print 1, 2, 3 in an arbitrary order
1325 /// for i in table.drain() {
1326 /// println!("{}", i);
1327 /// }
1328 ///
1329 /// assert!(table.is_empty());
1330 /// # }
1331 /// # fn main() {
1332 /// # #[cfg(feature = "nightly")]
1333 /// # test()
1334 /// # }
1335 /// ```
1336 pub fn drain(&mut self) -> Drain<'_, T, A> {
1337 Drain {
1338 inner: self.raw.drain(),
1339 }
1340 }
1341
1342 /// Drains elements which are true under the given predicate,
1343 /// and returns an iterator over the removed items.
1344 ///
1345 /// In other words, move all elements `e` such that `f(&e)` returns `true` out
1346 /// into another iterator.
1347 ///
1348 /// If the returned `ExtractIf` is not exhausted, e.g. because it is dropped without iterating
1349 /// or the iteration short-circuits, then the remaining elements will be retained.
1350 /// Use [`retain()`] with a negated predicate if you do not need the returned iterator.
1351 ///
1352 /// [`retain()`]: HashTable::retain
1353 ///
1354 /// # Examples
1355 ///
1356 /// ```
1357 /// # #[cfg(feature = "nightly")]
1358 /// # fn test() {
1359 /// use hashbrown::{HashTable, DefaultHashBuilder};
1360 /// use std::hash::BuildHasher;
1361 ///
1362 /// let mut table = HashTable::new();
1363 /// let hasher = DefaultHashBuilder::default();
1364 /// let hasher = |val: &_| hasher.hash_one(val);
1365 /// for x in 0..8 {
1366 /// table.insert_unique(hasher(&x), x, hasher);
1367 /// }
1368 /// let drained: Vec<i32> = table.extract_if(|&mut v| v % 2 == 0).collect();
1369 ///
1370 /// let mut evens = drained.into_iter().collect::<Vec<_>>();
1371 /// let mut odds = table.into_iter().collect::<Vec<_>>();
1372 /// evens.sort();
1373 /// odds.sort();
1374 ///
1375 /// assert_eq!(evens, vec![0, 2, 4, 6]);
1376 /// assert_eq!(odds, vec![1, 3, 5, 7]);
1377 /// # }
1378 /// # fn main() {
1379 /// # #[cfg(feature = "nightly")]
1380 /// # test()
1381 /// # }
1382 /// ```
1383 pub fn extract_if<F>(&mut self, f: F) -> ExtractIf<'_, T, F, A>
1384 where
1385 F: FnMut(&mut T) -> bool,
1386 {
1387 ExtractIf {
1388 f,
1389 inner: RawExtractIf {
1390 iter: unsafe { self.raw.iter() },
1391 table: &mut self.raw,
1392 },
1393 }
1394 }
1395
1396 /// Attempts to get mutable references to `N` values in the map at once.
1397 ///
1398 /// The `eq` argument should be a closure such that `eq(i, k)` returns true if `k` is equal to
1399 /// the `i`th key to be looked up.
1400 ///
1401 /// Returns an array of length `N` with the results of each query. For soundness, at most one
1402 /// mutable reference will be returned to any value. `None` will be used if the key is missing.
1403 ///
1404 /// # Panics
1405 ///
1406 /// Panics if any keys are overlapping.
1407 ///
1408 /// # Examples
1409 ///
1410 /// ```
1411 /// # #[cfg(feature = "nightly")]
1412 /// # fn test() {
1413 /// use hashbrown::hash_table::Entry;
1414 /// use hashbrown::{HashTable, DefaultHashBuilder};
1415 /// use std::hash::BuildHasher;
1416 ///
1417 /// let mut libraries: HashTable<(&str, u32)> = HashTable::new();
1418 /// let hasher = DefaultHashBuilder::default();
1419 /// let hasher = |val: &_| hasher.hash_one(val);
1420 /// for (k, v) in [
1421 /// ("Bodleian Library", 1602),
1422 /// ("Athenæum", 1807),
1423 /// ("Herzogin-Anna-Amalia-Bibliothek", 1691),
1424 /// ("Library of Congress", 1800),
1425 /// ] {
1426 /// libraries.insert_unique(hasher(&k), (k, v), |(k, _)| hasher(&k));
1427 /// }
1428 ///
1429 /// let keys = ["Athenæum", "Library of Congress"];
1430 /// let got = libraries.get_disjoint_mut(keys.map(|k| hasher(&k)), |i, val| keys[i] == val.0);
1431 /// assert_eq!(
1432 /// got,
1433 /// [Some(&mut ("Athenæum", 1807)), Some(&mut ("Library of Congress", 1800))],
1434 /// );
1435 ///
1436 /// // Missing keys result in None
1437 /// let keys = ["Athenæum", "New York Public Library"];
1438 /// let got = libraries.get_disjoint_mut(keys.map(|k| hasher(&k)), |i, val| keys[i] == val.0);
1439 /// assert_eq!(got, [Some(&mut ("Athenæum", 1807)), None]);
1440 /// # }
1441 /// # fn main() {
1442 /// # #[cfg(feature = "nightly")]
1443 /// # test()
1444 /// # }
1445 /// ```
1446 ///
1447 /// ```should_panic
1448 /// # #[cfg(feature = "nightly")]
1449 /// # fn test() {
1450 /// # use hashbrown::{HashTable, DefaultHashBuilder};
1451 /// # use std::hash::BuildHasher;
1452 ///
1453 /// let mut libraries: HashTable<(&str, u32)> = HashTable::new();
1454 /// let hasher = DefaultHashBuilder::default();
1455 /// let hasher = |val: &_| hasher.hash_one(val);
1456 /// for (k, v) in [
1457 /// ("Athenæum", 1807),
1458 /// ("Library of Congress", 1800),
1459 /// ] {
1460 /// libraries.insert_unique(hasher(&k), (k, v), |(k, _)| hasher(&k));
1461 /// }
1462 ///
1463 /// // Duplicate keys result in a panic!
1464 /// let keys = ["Athenæum", "Athenæum"];
1465 /// let got = libraries.get_disjoint_mut(keys.map(|k| hasher(&k)), |i, val| keys[i] == val.0);
1466 /// # }
1467 /// # fn main() {
1468 /// # #[cfg(feature = "nightly")]
1469 /// # test();
1470 /// # #[cfg(not(feature = "nightly"))]
1471 /// # panic!();
1472 /// # }
1473 /// ```
1474 pub fn get_disjoint_mut<const N: usize>(
1475 &mut self,
1476 hashes: [u64; N],
1477 eq: impl FnMut(usize, &T) -> bool,
1478 ) -> [Option<&'_ mut T>; N] {
1479 self.raw.get_disjoint_mut(hashes, eq)
1480 }
1481
1482 /// Attempts to get mutable references to `N` values in the map at once.
1483 #[deprecated(note = "use `get_disjoint_mut` instead")]
1484 pub fn get_many_mut<const N: usize>(
1485 &mut self,
1486 hashes: [u64; N],
1487 eq: impl FnMut(usize, &T) -> bool,
1488 ) -> [Option<&'_ mut T>; N] {
1489 self.raw.get_disjoint_mut(hashes, eq)
1490 }
1491
1492 /// Attempts to get mutable references to `N` values in the map at once, without validating that
1493 /// the values are unique.
1494 ///
1495 /// The `eq` argument should be a closure such that `eq(i, k)` returns true if `k` is equal to
1496 /// the `i`th key to be looked up.
1497 ///
1498 /// Returns an array of length `N` with the results of each query. `None` will be returned if
1499 /// any of the keys are missing.
1500 ///
1501 /// For a safe alternative see [`get_disjoint_mut`](`HashTable::get_disjoint_mut`).
1502 ///
1503 /// # Safety
1504 ///
1505 /// Calling this method with overlapping keys is *[undefined behavior]* even if the resulting
1506 /// references are not used.
1507 ///
1508 /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
1509 ///
1510 /// # Examples
1511 ///
1512 /// ```
1513 /// # #[cfg(feature = "nightly")]
1514 /// # fn test() {
1515 /// use hashbrown::hash_table::Entry;
1516 /// use hashbrown::{HashTable, DefaultHashBuilder};
1517 /// use std::hash::BuildHasher;
1518 ///
1519 /// let mut libraries: HashTable<(&str, u32)> = HashTable::new();
1520 /// let hasher = DefaultHashBuilder::default();
1521 /// let hasher = |val: &_| hasher.hash_one(val);
1522 /// for (k, v) in [
1523 /// ("Bodleian Library", 1602),
1524 /// ("Athenæum", 1807),
1525 /// ("Herzogin-Anna-Amalia-Bibliothek", 1691),
1526 /// ("Library of Congress", 1800),
1527 /// ] {
1528 /// libraries.insert_unique(hasher(&k), (k, v), |(k, _)| hasher(&k));
1529 /// }
1530 ///
1531 /// let keys = ["Athenæum", "Library of Congress"];
1532 /// let got = libraries.get_disjoint_mut(keys.map(|k| hasher(&k)), |i, val| keys[i] == val.0);
1533 /// assert_eq!(
1534 /// got,
1535 /// [Some(&mut ("Athenæum", 1807)), Some(&mut ("Library of Congress", 1800))],
1536 /// );
1537 ///
1538 /// // Missing keys result in None
1539 /// let keys = ["Athenæum", "New York Public Library"];
1540 /// let got = libraries.get_disjoint_mut(keys.map(|k| hasher(&k)), |i, val| keys[i] == val.0);
1541 /// assert_eq!(got, [Some(&mut ("Athenæum", 1807)), None]);
1542 /// # }
1543 /// # fn main() {
1544 /// # #[cfg(feature = "nightly")]
1545 /// # test()
1546 /// # }
1547 /// ```
1548 pub unsafe fn get_disjoint_unchecked_mut<const N: usize>(
1549 &mut self,
1550 hashes: [u64; N],
1551 eq: impl FnMut(usize, &T) -> bool,
1552 ) -> [Option<&'_ mut T>; N] {
1553 unsafe { self.raw.get_disjoint_unchecked_mut(hashes, eq) }
1554 }
1555
1556 /// Attempts to get mutable references to `N` values in the map at once, without validating that
1557 /// the values are unique.
1558 #[deprecated(note = "use `get_disjoint_unchecked_mut` instead")]
1559 pub unsafe fn get_many_unchecked_mut<const N: usize>(
1560 &mut self,
1561 hashes: [u64; N],
1562 eq: impl FnMut(usize, &T) -> bool,
1563 ) -> [Option<&'_ mut T>; N] {
1564 unsafe { self.raw.get_disjoint_unchecked_mut(hashes, eq) }
1565 }
1566
1567 /// Returns the total amount of memory allocated internally by the hash
1568 /// table, in bytes.
1569 ///
1570 /// The returned number is informational only. It is intended to be
1571 /// primarily used for memory profiling.
1572 #[inline]
1573 pub fn allocation_size(&self) -> usize {
1574 self.raw.allocation_size()
1575 }
1576}
1577
1578impl<T, A> IntoIterator for HashTable<T, A>
1579where
1580 A: Allocator,
1581{
1582 type Item = T;
1583 type IntoIter = IntoIter<T, A>;
1584
1585 fn into_iter(self) -> IntoIter<T, A> {
1586 IntoIter {
1587 inner: self.raw.into_iter(),
1588 }
1589 }
1590}
1591
1592impl<'a, T, A> IntoIterator for &'a HashTable<T, A>
1593where
1594 A: Allocator,
1595{
1596 type Item = &'a T;
1597 type IntoIter = Iter<'a, T>;
1598
1599 fn into_iter(self) -> Iter<'a, T> {
1600 self.iter()
1601 }
1602}
1603
1604impl<'a, T, A> IntoIterator for &'a mut HashTable<T, A>
1605where
1606 A: Allocator,
1607{
1608 type Item = &'a mut T;
1609 type IntoIter = IterMut<'a, T>;
1610
1611 fn into_iter(self) -> IterMut<'a, T> {
1612 self.iter_mut()
1613 }
1614}
1615
1616impl<T, A> Default for HashTable<T, A>
1617where
1618 A: Allocator + Default,
1619{
1620 fn default() -> Self {
1621 Self {
1622 raw: Default::default(),
1623 }
1624 }
1625}
1626
1627impl<T, A> Clone for HashTable<T, A>
1628where
1629 T: Clone,
1630 A: Allocator + Clone,
1631{
1632 fn clone(&self) -> Self {
1633 Self {
1634 raw: self.raw.clone(),
1635 }
1636 }
1637
1638 fn clone_from(&mut self, source: &Self) {
1639 self.raw.clone_from(&source.raw);
1640 }
1641}
1642
1643impl<T, A> fmt::Debug for HashTable<T, A>
1644where
1645 T: fmt::Debug,
1646 A: Allocator,
1647{
1648 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1649 f.debug_set().entries(self.iter()).finish()
1650 }
1651}
1652
1653/// A view into a single entry in a table, which may either be vacant or occupied.
1654///
1655/// This `enum` is constructed from the [`entry`] method on [`HashTable`].
1656///
1657/// [`entry`]: HashTable::entry
1658///
1659/// # Examples
1660///
1661/// ```
1662/// # #[cfg(feature = "nightly")]
1663/// # fn test() {
1664/// use hashbrown::hash_table::{Entry, OccupiedEntry};
1665/// use hashbrown::{HashTable, DefaultHashBuilder};
1666/// use std::hash::BuildHasher;
1667///
1668/// let mut table = HashTable::new();
1669/// let hasher = DefaultHashBuilder::default();
1670/// let hasher = |val: &_| hasher.hash_one(val);
1671/// for x in ["a", "b", "c"] {
1672/// table.insert_unique(hasher(&x), x, hasher);
1673/// }
1674/// assert_eq!(table.len(), 3);
1675///
1676/// // Existing value (insert)
1677/// let entry: Entry<_> = table.entry(hasher(&"a"), |&x| x == "a", hasher);
1678/// let _raw_o: OccupiedEntry<_, _> = entry.insert("a");
1679/// assert_eq!(table.len(), 3);
1680/// // Nonexistent value (insert)
1681/// table.entry(hasher(&"d"), |&x| x == "d", hasher).insert("d");
1682///
1683/// // Existing value (or_insert)
1684/// table
1685/// .entry(hasher(&"b"), |&x| x == "b", hasher)
1686/// .or_insert("b");
1687/// // Nonexistent value (or_insert)
1688/// table
1689/// .entry(hasher(&"e"), |&x| x == "e", hasher)
1690/// .or_insert("e");
1691///
1692/// println!("Our HashTable: {:?}", table);
1693///
1694/// let mut vec: Vec<_> = table.iter().copied().collect();
1695/// // The `Iter` iterator produces items in arbitrary order, so the
1696/// // items must be sorted to test them against a sorted array.
1697/// vec.sort_unstable();
1698/// assert_eq!(vec, ["a", "b", "c", "d", "e"]);
1699/// # }
1700/// # fn main() {
1701/// # #[cfg(feature = "nightly")]
1702/// # test()
1703/// # }
1704/// ```
1705pub enum Entry<'a, T, A = Global>
1706where
1707 A: Allocator,
1708{
1709 /// An occupied entry.
1710 ///
1711 /// # Examples
1712 ///
1713 /// ```
1714 /// # #[cfg(feature = "nightly")]
1715 /// # fn test() {
1716 /// use hashbrown::hash_table::{Entry, OccupiedEntry};
1717 /// use hashbrown::{HashTable, DefaultHashBuilder};
1718 /// use std::hash::BuildHasher;
1719 ///
1720 /// let mut table = HashTable::new();
1721 /// let hasher = DefaultHashBuilder::default();
1722 /// let hasher = |val: &_| hasher.hash_one(val);
1723 /// for x in ["a", "b"] {
1724 /// table.insert_unique(hasher(&x), x, hasher);
1725 /// }
1726 ///
1727 /// match table.entry(hasher(&"a"), |&x| x == "a", hasher) {
1728 /// Entry::Vacant(_) => unreachable!(),
1729 /// Entry::Occupied(_) => {}
1730 /// }
1731 /// # }
1732 /// # fn main() {
1733 /// # #[cfg(feature = "nightly")]
1734 /// # test()
1735 /// # }
1736 /// ```
1737 Occupied(OccupiedEntry<'a, T, A>),
1738
1739 /// A vacant entry.
1740 ///
1741 /// # Examples
1742 ///
1743 /// ```
1744 /// # #[cfg(feature = "nightly")]
1745 /// # fn test() {
1746 /// use hashbrown::hash_table::{Entry, OccupiedEntry};
1747 /// use hashbrown::{HashTable, DefaultHashBuilder};
1748 /// use std::hash::BuildHasher;
1749 ///
1750 /// let mut table = HashTable::<&str>::new();
1751 /// let hasher = DefaultHashBuilder::default();
1752 /// let hasher = |val: &_| hasher.hash_one(val);
1753 ///
1754 /// match table.entry(hasher(&"a"), |&x| x == "a", hasher) {
1755 /// Entry::Vacant(_) => {}
1756 /// Entry::Occupied(_) => unreachable!(),
1757 /// }
1758 /// # }
1759 /// # fn main() {
1760 /// # #[cfg(feature = "nightly")]
1761 /// # test()
1762 /// # }
1763 /// ```
1764 Vacant(VacantEntry<'a, T, A>),
1765}
1766
1767impl<T: fmt::Debug, A: Allocator> fmt::Debug for Entry<'_, T, A> {
1768 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1769 match *self {
1770 Entry::Vacant(ref v) => f.debug_tuple("Entry").field(v).finish(),
1771 Entry::Occupied(ref o) => f.debug_tuple("Entry").field(o).finish(),
1772 }
1773 }
1774}
1775
1776impl<'a, T, A> Entry<'a, T, A>
1777where
1778 A: Allocator,
1779{
1780 /// Sets the value of the entry, replacing any existing value if there is
1781 /// one, and returns an [`OccupiedEntry`].
1782 ///
1783 /// # Examples
1784 ///
1785 /// ```
1786 /// # #[cfg(feature = "nightly")]
1787 /// # fn test() {
1788 /// use hashbrown::{HashTable, DefaultHashBuilder};
1789 /// use std::hash::BuildHasher;
1790 ///
1791 /// let mut table: HashTable<&str> = HashTable::new();
1792 /// let hasher = DefaultHashBuilder::default();
1793 /// let hasher = |val: &_| hasher.hash_one(val);
1794 ///
1795 /// let entry = table
1796 /// .entry(hasher(&"horseyland"), |&x| x == "horseyland", hasher)
1797 /// .insert("horseyland");
1798 ///
1799 /// assert_eq!(entry.get(), &"horseyland");
1800 /// # }
1801 /// # fn main() {
1802 /// # #[cfg(feature = "nightly")]
1803 /// # test()
1804 /// # }
1805 /// ```
1806 pub fn insert(self, value: T) -> OccupiedEntry<'a, T, A> {
1807 match self {
1808 Entry::Occupied(mut entry) => {
1809 *entry.get_mut() = value;
1810 entry
1811 }
1812 Entry::Vacant(entry) => entry.insert(value),
1813 }
1814 }
1815
1816 /// Ensures a value is in the entry by inserting if it was vacant.
1817 ///
1818 /// Returns an [`OccupiedEntry`] pointing to the now-occupied entry.
1819 ///
1820 /// # Examples
1821 ///
1822 /// ```
1823 /// # #[cfg(feature = "nightly")]
1824 /// # fn test() {
1825 /// use hashbrown::{HashTable, DefaultHashBuilder};
1826 /// use std::hash::BuildHasher;
1827 ///
1828 /// let mut table: HashTable<&str> = HashTable::new();
1829 /// let hasher = DefaultHashBuilder::default();
1830 /// let hasher = |val: &_| hasher.hash_one(val);
1831 ///
1832 /// // nonexistent key
1833 /// table
1834 /// .entry(hasher(&"poneyland"), |&x| x == "poneyland", hasher)
1835 /// .or_insert("poneyland");
1836 /// assert!(table
1837 /// .find(hasher(&"poneyland"), |&x| x == "poneyland")
1838 /// .is_some());
1839 ///
1840 /// // existing key
1841 /// table
1842 /// .entry(hasher(&"poneyland"), |&x| x == "poneyland", hasher)
1843 /// .or_insert("poneyland");
1844 /// assert!(table
1845 /// .find(hasher(&"poneyland"), |&x| x == "poneyland")
1846 /// .is_some());
1847 /// assert_eq!(table.len(), 1);
1848 /// # }
1849 /// # fn main() {
1850 /// # #[cfg(feature = "nightly")]
1851 /// # test()
1852 /// # }
1853 /// ```
1854 pub fn or_insert(self, default: T) -> OccupiedEntry<'a, T, A> {
1855 match self {
1856 Entry::Occupied(entry) => entry,
1857 Entry::Vacant(entry) => entry.insert(default),
1858 }
1859 }
1860
1861 /// Ensures a value is in the entry by inserting the result of the default function if empty..
1862 ///
1863 /// Returns an [`OccupiedEntry`] pointing to the now-occupied entry.
1864 ///
1865 /// # Examples
1866 ///
1867 /// ```
1868 /// # #[cfg(feature = "nightly")]
1869 /// # fn test() {
1870 /// use hashbrown::{HashTable, DefaultHashBuilder};
1871 /// use std::hash::BuildHasher;
1872 ///
1873 /// let mut table: HashTable<String> = HashTable::new();
1874 /// let hasher = DefaultHashBuilder::default();
1875 /// let hasher = |val: &_| hasher.hash_one(val);
1876 ///
1877 /// table
1878 /// .entry(hasher("poneyland"), |x| x == "poneyland", |val| hasher(val))
1879 /// .or_insert_with(|| "poneyland".to_string());
1880 ///
1881 /// assert!(table
1882 /// .find(hasher(&"poneyland"), |x| x == "poneyland")
1883 /// .is_some());
1884 /// # }
1885 /// # fn main() {
1886 /// # #[cfg(feature = "nightly")]
1887 /// # test()
1888 /// # }
1889 /// ```
1890 pub fn or_insert_with(self, default: impl FnOnce() -> T) -> OccupiedEntry<'a, T, A> {
1891 match self {
1892 Entry::Occupied(entry) => entry,
1893 Entry::Vacant(entry) => entry.insert(default()),
1894 }
1895 }
1896
1897 /// Provides in-place mutable access to an occupied entry before any
1898 /// potential inserts into the table.
1899 ///
1900 /// # Examples
1901 ///
1902 /// ```
1903 /// # #[cfg(feature = "nightly")]
1904 /// # fn test() {
1905 /// use hashbrown::{HashTable, DefaultHashBuilder};
1906 /// use std::hash::BuildHasher;
1907 ///
1908 /// let mut table: HashTable<(&str, u32)> = HashTable::new();
1909 /// let hasher = DefaultHashBuilder::default();
1910 /// let hasher = |val: &_| hasher.hash_one(val);
1911 ///
1912 /// table
1913 /// .entry(
1914 /// hasher(&"poneyland"),
1915 /// |&(x, _)| x == "poneyland",
1916 /// |(k, _)| hasher(&k),
1917 /// )
1918 /// .and_modify(|(_, v)| *v += 1)
1919 /// .or_insert(("poneyland", 42));
1920 /// assert_eq!(
1921 /// table.find(hasher(&"poneyland"), |&(k, _)| k == "poneyland"),
1922 /// Some(&("poneyland", 42))
1923 /// );
1924 ///
1925 /// table
1926 /// .entry(
1927 /// hasher(&"poneyland"),
1928 /// |&(x, _)| x == "poneyland",
1929 /// |(k, _)| hasher(&k),
1930 /// )
1931 /// .and_modify(|(_, v)| *v += 1)
1932 /// .or_insert(("poneyland", 42));
1933 /// assert_eq!(
1934 /// table.find(hasher(&"poneyland"), |&(k, _)| k == "poneyland"),
1935 /// Some(&("poneyland", 43))
1936 /// );
1937 /// # }
1938 /// # fn main() {
1939 /// # #[cfg(feature = "nightly")]
1940 /// # test()
1941 /// # }
1942 /// ```
1943 pub fn and_modify(self, f: impl FnOnce(&mut T)) -> Self {
1944 match self {
1945 Entry::Occupied(mut entry) => {
1946 f(entry.get_mut());
1947 Entry::Occupied(entry)
1948 }
1949 Entry::Vacant(entry) => Entry::Vacant(entry),
1950 }
1951 }
1952
1953 /// Converts the `Entry` into a mutable reference to the underlying table.
1954 pub fn into_table(self) -> &'a mut HashTable<T, A> {
1955 match self {
1956 Entry::Occupied(entry) => entry.table,
1957 Entry::Vacant(entry) => entry.table,
1958 }
1959 }
1960}
1961
1962/// A view into an occupied entry in a `HashTable`.
1963/// It is part of the [`Entry`] enum.
1964///
1965/// # Examples
1966///
1967/// ```
1968/// # #[cfg(feature = "nightly")]
1969/// # fn test() {
1970/// use hashbrown::hash_table::{Entry, OccupiedEntry};
1971/// use hashbrown::{HashTable, DefaultHashBuilder};
1972/// use std::hash::BuildHasher;
1973///
1974/// let mut table = HashTable::new();
1975/// let hasher = DefaultHashBuilder::default();
1976/// let hasher = |val: &_| hasher.hash_one(val);
1977/// for x in ["a", "b", "c"] {
1978/// table.insert_unique(hasher(&x), x, hasher);
1979/// }
1980/// assert_eq!(table.len(), 3);
1981///
1982/// let _entry_o: OccupiedEntry<_, _> = table.find_entry(hasher(&"a"), |&x| x == "a").unwrap();
1983/// assert_eq!(table.len(), 3);
1984///
1985/// // Existing key
1986/// match table.entry(hasher(&"a"), |&x| x == "a", hasher) {
1987/// Entry::Vacant(_) => unreachable!(),
1988/// Entry::Occupied(view) => {
1989/// assert_eq!(view.get(), &"a");
1990/// }
1991/// }
1992///
1993/// assert_eq!(table.len(), 3);
1994///
1995/// // Existing key (take)
1996/// match table.entry(hasher(&"c"), |&x| x == "c", hasher) {
1997/// Entry::Vacant(_) => unreachable!(),
1998/// Entry::Occupied(view) => {
1999/// assert_eq!(view.remove().0, "c");
2000/// }
2001/// }
2002/// assert_eq!(table.find(hasher(&"c"), |&x| x == "c"), None);
2003/// assert_eq!(table.len(), 2);
2004/// # }
2005/// # fn main() {
2006/// # #[cfg(feature = "nightly")]
2007/// # test()
2008/// # }
2009/// ```
2010pub struct OccupiedEntry<'a, T, A = Global>
2011where
2012 A: Allocator,
2013{
2014 bucket: Bucket<T>,
2015 table: &'a mut HashTable<T, A>,
2016}
2017
2018unsafe impl<T, A> Send for OccupiedEntry<'_, T, A>
2019where
2020 T: Send,
2021 A: Send + Allocator,
2022{
2023}
2024unsafe impl<T, A> Sync for OccupiedEntry<'_, T, A>
2025where
2026 T: Sync,
2027 A: Sync + Allocator,
2028{
2029}
2030
2031impl<T: fmt::Debug, A: Allocator> fmt::Debug for OccupiedEntry<'_, T, A> {
2032 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2033 f.debug_struct("OccupiedEntry")
2034 .field("value", self.get())
2035 .finish()
2036 }
2037}
2038
2039impl<'a, T, A> OccupiedEntry<'a, T, A>
2040where
2041 A: Allocator,
2042{
2043 /// Takes the value out of the entry, and returns it along with a
2044 /// `VacantEntry` that can be used to insert another value with the same
2045 /// hash as the one that was just removed.
2046 ///
2047 /// # Examples
2048 ///
2049 /// ```
2050 /// # #[cfg(feature = "nightly")]
2051 /// # fn test() {
2052 /// use hashbrown::hash_table::Entry;
2053 /// use hashbrown::{HashTable, DefaultHashBuilder};
2054 /// use std::hash::BuildHasher;
2055 ///
2056 /// let mut table: HashTable<&str> = HashTable::new();
2057 /// let hasher = DefaultHashBuilder::default();
2058 /// let hasher = |val: &_| hasher.hash_one(val);
2059 /// // The table is empty
2060 /// assert!(table.is_empty() && table.capacity() == 0);
2061 ///
2062 /// table.insert_unique(hasher(&"poneyland"), "poneyland", hasher);
2063 /// let capacity_before_remove = table.capacity();
2064 ///
2065 /// if let Entry::Occupied(o) = table.entry(hasher(&"poneyland"), |&x| x == "poneyland", hasher) {
2066 /// assert_eq!(o.remove().0, "poneyland");
2067 /// }
2068 ///
2069 /// assert!(table
2070 /// .find(hasher(&"poneyland"), |&x| x == "poneyland")
2071 /// .is_none());
2072 /// // Now table hold none elements but capacity is equal to the old one
2073 /// assert!(table.len() == 0 && table.capacity() == capacity_before_remove);
2074 /// # }
2075 /// # fn main() {
2076 /// # #[cfg(feature = "nightly")]
2077 /// # test()
2078 /// # }
2079 /// ```
2080 #[cfg_attr(feature = "inline-more", inline)]
2081 pub fn remove(self) -> (T, VacantEntry<'a, T, A>) {
2082 let (val, index, tag) = unsafe { self.table.raw.remove_tagged(self.bucket) };
2083 (
2084 val,
2085 VacantEntry {
2086 tag,
2087 index,
2088 table: self.table,
2089 },
2090 )
2091 }
2092
2093 /// Gets a reference to the value in the entry.
2094 ///
2095 /// # Examples
2096 ///
2097 /// ```
2098 /// # #[cfg(feature = "nightly")]
2099 /// # fn test() {
2100 /// use hashbrown::hash_table::Entry;
2101 /// use hashbrown::{HashTable, DefaultHashBuilder};
2102 /// use std::hash::BuildHasher;
2103 ///
2104 /// let mut table: HashTable<&str> = HashTable::new();
2105 /// let hasher = DefaultHashBuilder::default();
2106 /// let hasher = |val: &_| hasher.hash_one(val);
2107 /// table.insert_unique(hasher(&"poneyland"), "poneyland", hasher);
2108 ///
2109 /// match table.entry(hasher(&"poneyland"), |&x| x == "poneyland", hasher) {
2110 /// Entry::Vacant(_) => panic!(),
2111 /// Entry::Occupied(entry) => assert_eq!(entry.get(), &"poneyland"),
2112 /// }
2113 /// # }
2114 /// # fn main() {
2115 /// # #[cfg(feature = "nightly")]
2116 /// # test()
2117 /// # }
2118 /// ```
2119 #[inline]
2120 pub fn get(&self) -> &T {
2121 unsafe { self.bucket.as_ref() }
2122 }
2123
2124 /// Gets a mutable reference to the value in the entry.
2125 ///
2126 /// If you need a reference to the `OccupiedEntry` which may outlive the
2127 /// destruction of the `Entry` value, see [`into_mut`].
2128 ///
2129 /// [`into_mut`]: #method.into_mut
2130 ///
2131 /// # Examples
2132 ///
2133 /// ```
2134 /// # #[cfg(feature = "nightly")]
2135 /// # fn test() {
2136 /// use hashbrown::hash_table::Entry;
2137 /// use hashbrown::{HashTable, DefaultHashBuilder};
2138 /// use std::hash::BuildHasher;
2139 ///
2140 /// let mut table: HashTable<(&str, u32)> = HashTable::new();
2141 /// let hasher = DefaultHashBuilder::default();
2142 /// let hasher = |val: &_| hasher.hash_one(val);
2143 /// table.insert_unique(hasher(&"poneyland"), ("poneyland", 12), |(k, _)| hasher(&k));
2144 ///
2145 /// assert_eq!(
2146 /// table.find(hasher(&"poneyland"), |&(x, _)| x == "poneyland",),
2147 /// Some(&("poneyland", 12))
2148 /// );
2149 ///
2150 /// if let Entry::Occupied(mut o) = table.entry(
2151 /// hasher(&"poneyland"),
2152 /// |&(x, _)| x == "poneyland",
2153 /// |(k, _)| hasher(&k),
2154 /// ) {
2155 /// o.get_mut().1 += 10;
2156 /// assert_eq!(o.get().1, 22);
2157 ///
2158 /// // We can use the same Entry multiple times.
2159 /// o.get_mut().1 += 2;
2160 /// }
2161 ///
2162 /// assert_eq!(
2163 /// table.find(hasher(&"poneyland"), |&(x, _)| x == "poneyland",),
2164 /// Some(&("poneyland", 24))
2165 /// );
2166 /// # }
2167 /// # fn main() {
2168 /// # #[cfg(feature = "nightly")]
2169 /// # test()
2170 /// # }
2171 /// ```
2172 #[inline]
2173 pub fn get_mut(&mut self) -> &mut T {
2174 unsafe { self.bucket.as_mut() }
2175 }
2176
2177 /// Converts the `OccupiedEntry` into a mutable reference to the value in the entry
2178 /// with a lifetime bound to the table itself.
2179 ///
2180 /// If you need multiple references to the `OccupiedEntry`, see [`get_mut`].
2181 ///
2182 /// [`get_mut`]: #method.get_mut
2183 ///
2184 /// # Examples
2185 ///
2186 /// ```
2187 /// # #[cfg(feature = "nightly")]
2188 /// # fn test() {
2189 /// use hashbrown::hash_table::Entry;
2190 /// use hashbrown::{HashTable, DefaultHashBuilder};
2191 /// use std::hash::BuildHasher;
2192 ///
2193 /// let mut table: HashTable<(&str, u32)> = HashTable::new();
2194 /// let hasher = DefaultHashBuilder::default();
2195 /// let hasher = |val: &_| hasher.hash_one(val);
2196 /// table.insert_unique(hasher(&"poneyland"), ("poneyland", 12), |(k, _)| hasher(&k));
2197 ///
2198 /// assert_eq!(
2199 /// table.find(hasher(&"poneyland"), |&(x, _)| x == "poneyland",),
2200 /// Some(&("poneyland", 12))
2201 /// );
2202 ///
2203 /// let value: &mut (&str, u32);
2204 /// match table.entry(
2205 /// hasher(&"poneyland"),
2206 /// |&(x, _)| x == "poneyland",
2207 /// |(k, _)| hasher(&k),
2208 /// ) {
2209 /// Entry::Occupied(entry) => value = entry.into_mut(),
2210 /// Entry::Vacant(_) => panic!(),
2211 /// }
2212 /// value.1 += 10;
2213 ///
2214 /// assert_eq!(
2215 /// table.find(hasher(&"poneyland"), |&(x, _)| x == "poneyland",),
2216 /// Some(&("poneyland", 22))
2217 /// );
2218 /// # }
2219 /// # fn main() {
2220 /// # #[cfg(feature = "nightly")]
2221 /// # test()
2222 /// # }
2223 /// ```
2224 pub fn into_mut(self) -> &'a mut T {
2225 unsafe { self.bucket.as_mut() }
2226 }
2227
2228 /// Converts the `OccupiedEntry` into a mutable reference to the underlying
2229 /// table.
2230 pub fn into_table(self) -> &'a mut HashTable<T, A> {
2231 self.table
2232 }
2233
2234 /// Returns the bucket index in the table for this entry.
2235 ///
2236 /// This can be used to store a borrow-free "reference" to the entry, later using
2237 /// [`HashTable::get_bucket`], [`HashTable::get_bucket_mut`], or
2238 /// [`HashTable::get_bucket_entry`] to access it again without hash probing.
2239 ///
2240 /// The index is only meaningful as long as the table is not resized and no entries are added
2241 /// or removed. After such changes, it may end up pointing to a different entry or none at all.
2242 ///
2243 /// # Examples
2244 ///
2245 /// ```
2246 /// # #[cfg(feature = "nightly")]
2247 /// # fn test() {
2248 /// use hashbrown::{HashTable, DefaultHashBuilder};
2249 /// use std::hash::BuildHasher;
2250 ///
2251 /// let mut table = HashTable::new();
2252 /// let hasher = DefaultHashBuilder::default();
2253 /// let hasher = |val: &_| hasher.hash_one(val);
2254 /// table.insert_unique(hasher(&1), (1, 1), |val| hasher(&val.0));
2255 /// table.insert_unique(hasher(&2), (2, 2), |val| hasher(&val.0));
2256 /// table.insert_unique(hasher(&3), (3, 3), |val| hasher(&val.0));
2257 ///
2258 /// let index = table
2259 /// .entry(hasher(&2), |val| val.0 == 2, |val| hasher(&val.0))
2260 /// .or_insert((2, -2))
2261 /// .bucket_index();
2262 /// assert_eq!(table.get_bucket(index), Some(&(2, 2)));
2263 ///
2264 /// // Full mutation would invalidate any normal reference
2265 /// for (_key, value) in &mut table {
2266 /// *value *= 11;
2267 /// }
2268 ///
2269 /// // The index still reaches the same key with the updated value
2270 /// assert_eq!(table.get_bucket(index), Some(&(2, 22)));
2271 /// # }
2272 /// # fn main() {
2273 /// # #[cfg(feature = "nightly")]
2274 /// # test()
2275 /// # }
2276 /// ```
2277 pub fn bucket_index(&self) -> usize {
2278 unsafe { self.table.raw.bucket_index(&self.bucket) }
2279 }
2280
2281 /// Provides owned access to the value of the entry and allows to replace or
2282 /// remove it based on the value of the returned option.
2283 ///
2284 /// The hash of the new item should be the same as the old item.
2285 ///
2286 /// # Examples
2287 ///
2288 /// ```
2289 /// # #[cfg(feature = "nightly")]
2290 /// # fn test() {
2291 /// use hashbrown::{HashTable, DefaultHashBuilder};
2292 /// use hashbrown::hash_table::Entry;
2293 /// use std::hash::BuildHasher;
2294 ///
2295 /// let mut table = HashTable::new();
2296 /// let hasher = DefaultHashBuilder::default();
2297 /// let hasher = |(key, _): &_| hasher.hash_one(key);
2298 /// table.insert_unique(hasher(&("poneyland", 42)), ("poneyland", 42), hasher);
2299 ///
2300 /// let entry = match table.entry(hasher(&("poneyland", 42)), |entry| entry.0 == "poneyland", hasher) {
2301 /// Entry::Occupied(e) => unsafe {
2302 /// e.replace_entry_with(|(k, v)| {
2303 /// assert_eq!(k, "poneyland");
2304 /// assert_eq!(v, 42);
2305 /// Some(("poneyland", v + 1))
2306 /// })
2307 /// }
2308 /// Entry::Vacant(_) => panic!(),
2309 /// };
2310 ///
2311 /// match entry {
2312 /// Entry::Occupied(e) => {
2313 /// assert_eq!(e.get(), &("poneyland", 43));
2314 /// }
2315 /// Entry::Vacant(_) => panic!(),
2316 /// }
2317 ///
2318 /// let entry = match table.entry(hasher(&("poneyland", 43)), |entry| entry.0 == "poneyland", hasher) {
2319 /// Entry::Occupied(e) => unsafe { e.replace_entry_with(|(_k, _v)| None) },
2320 /// Entry::Vacant(_) => panic!(),
2321 /// };
2322 ///
2323 /// match entry {
2324 /// Entry::Vacant(e) => {
2325 /// // nice!
2326 /// }
2327 /// Entry::Occupied(_) => panic!(),
2328 /// }
2329 ///
2330 /// assert!(table.is_empty());
2331 /// # }
2332 /// # fn main() {
2333 /// # #[cfg(feature = "nightly")]
2334 /// # test()
2335 /// # }
2336 /// ```
2337 #[cfg_attr(feature = "inline-more", inline)]
2338 pub fn replace_entry_with<F>(self, f: F) -> Entry<'a, T, A>
2339 where
2340 F: FnOnce(T) -> Option<T>,
2341 {
2342 unsafe {
2343 match self.table.raw.replace_bucket_with(self.bucket.clone(), f) {
2344 None => Entry::Occupied(self),
2345 Some(tag) => Entry::Vacant(VacantEntry {
2346 tag,
2347 index: self.bucket_index(),
2348 table: self.table,
2349 }),
2350 }
2351 }
2352 }
2353}
2354
2355/// A view into a vacant entry in a `HashTable`.
2356/// It is part of the [`Entry`] enum.
2357///
2358/// # Examples
2359///
2360/// ```
2361/// # #[cfg(feature = "nightly")]
2362/// # fn test() {
2363/// use hashbrown::hash_table::{Entry, VacantEntry};
2364/// use hashbrown::{HashTable, DefaultHashBuilder};
2365/// use std::hash::BuildHasher;
2366///
2367/// let mut table: HashTable<&str> = HashTable::new();
2368/// let hasher = DefaultHashBuilder::default();
2369/// let hasher = |val: &_| hasher.hash_one(val);
2370///
2371/// let entry_v: VacantEntry<_, _> = match table.entry(hasher(&"a"), |&x| x == "a", hasher) {
2372/// Entry::Vacant(view) => view,
2373/// Entry::Occupied(_) => unreachable!(),
2374/// };
2375/// entry_v.insert("a");
2376/// assert!(table.find(hasher(&"a"), |&x| x == "a").is_some() && table.len() == 1);
2377///
2378/// // Nonexistent key (insert)
2379/// match table.entry(hasher(&"b"), |&x| x == "b", hasher) {
2380/// Entry::Vacant(view) => {
2381/// view.insert("b");
2382/// }
2383/// Entry::Occupied(_) => unreachable!(),
2384/// }
2385/// assert!(table.find(hasher(&"b"), |&x| x == "b").is_some() && table.len() == 2);
2386/// # }
2387/// # fn main() {
2388/// # #[cfg(feature = "nightly")]
2389/// # test()
2390/// # }
2391/// ```
2392pub struct VacantEntry<'a, T, A = Global>
2393where
2394 A: Allocator,
2395{
2396 tag: Tag,
2397 index: usize,
2398 table: &'a mut HashTable<T, A>,
2399}
2400
2401impl<T: fmt::Debug, A: Allocator> fmt::Debug for VacantEntry<'_, T, A> {
2402 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2403 f.write_str("VacantEntry")
2404 }
2405}
2406
2407impl<'a, T, A> VacantEntry<'a, T, A>
2408where
2409 A: Allocator,
2410{
2411 /// Inserts a new element into the table with the hash that was used to
2412 /// obtain the `VacantEntry`.
2413 ///
2414 /// An `OccupiedEntry` is returned for the newly inserted element.
2415 ///
2416 /// # Examples
2417 ///
2418 /// ```
2419 /// # #[cfg(feature = "nightly")]
2420 /// # fn test() {
2421 /// use hashbrown::hash_table::Entry;
2422 /// use hashbrown::{HashTable, DefaultHashBuilder};
2423 /// use std::hash::BuildHasher;
2424 ///
2425 /// let mut table: HashTable<&str> = HashTable::new();
2426 /// let hasher = DefaultHashBuilder::default();
2427 /// let hasher = |val: &_| hasher.hash_one(val);
2428 ///
2429 /// if let Entry::Vacant(o) = table.entry(hasher(&"poneyland"), |&x| x == "poneyland", hasher) {
2430 /// o.insert("poneyland");
2431 /// }
2432 /// assert_eq!(
2433 /// table.find(hasher(&"poneyland"), |&x| x == "poneyland"),
2434 /// Some(&"poneyland")
2435 /// );
2436 /// # }
2437 /// # fn main() {
2438 /// # #[cfg(feature = "nightly")]
2439 /// # test()
2440 /// # }
2441 /// ```
2442 #[inline]
2443 pub fn insert(self, value: T) -> OccupiedEntry<'a, T, A> {
2444 let bucket = unsafe {
2445 self.table
2446 .raw
2447 .insert_tagged_at_index(self.tag, self.index, value)
2448 };
2449 OccupiedEntry {
2450 bucket,
2451 table: self.table,
2452 }
2453 }
2454
2455 /// Converts the `VacantEntry` into a mutable reference to the underlying
2456 /// table.
2457 pub fn into_table(self) -> &'a mut HashTable<T, A> {
2458 self.table
2459 }
2460}
2461
2462/// Type representing the absence of an entry, as returned by [`HashTable::find_entry`]
2463/// and [`HashTable::get_bucket_entry`].
2464///
2465/// This type only exists due to [limitations] in Rust's NLL borrow checker. In
2466/// the future, those methods will return an `Option<OccupiedEntry>` and this
2467/// type will be removed.
2468///
2469/// [limitations]: https://smallcultfollowing.com/babysteps/blog/2018/06/15/mir-based-borrow-check-nll-status-update/#polonius
2470///
2471/// # Examples
2472///
2473/// ```
2474/// # #[cfg(feature = "nightly")]
2475/// # fn test() {
2476/// use hashbrown::hash_table::{AbsentEntry, Entry};
2477/// use hashbrown::{HashTable, DefaultHashBuilder};
2478/// use std::hash::BuildHasher;
2479///
2480/// let mut table: HashTable<&str> = HashTable::new();
2481/// let hasher = DefaultHashBuilder::default();
2482/// let hasher = |val: &_| hasher.hash_one(val);
2483///
2484/// let entry_v: AbsentEntry<_, _> = table.find_entry(hasher(&"a"), |&x| x == "a").unwrap_err();
2485/// entry_v
2486/// .into_table()
2487/// .insert_unique(hasher(&"a"), "a", hasher);
2488/// assert!(table.find(hasher(&"a"), |&x| x == "a").is_some() && table.len() == 1);
2489///
2490/// // Nonexistent key (insert)
2491/// match table.entry(hasher(&"b"), |&x| x == "b", hasher) {
2492/// Entry::Vacant(view) => {
2493/// view.insert("b");
2494/// }
2495/// Entry::Occupied(_) => unreachable!(),
2496/// }
2497/// assert!(table.find(hasher(&"b"), |&x| x == "b").is_some() && table.len() == 2);
2498/// # }
2499/// # fn main() {
2500/// # #[cfg(feature = "nightly")]
2501/// # test()
2502/// # }
2503/// ```
2504pub struct AbsentEntry<'a, T, A = Global>
2505where
2506 A: Allocator,
2507{
2508 table: &'a mut HashTable<T, A>,
2509}
2510
2511impl<T: fmt::Debug, A: Allocator> fmt::Debug for AbsentEntry<'_, T, A> {
2512 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2513 f.write_str("AbsentEntry")
2514 }
2515}
2516
2517impl<'a, T, A> AbsentEntry<'a, T, A>
2518where
2519 A: Allocator,
2520{
2521 /// Converts the `AbsentEntry` into a mutable reference to the underlying
2522 /// table.
2523 pub fn into_table(self) -> &'a mut HashTable<T, A> {
2524 self.table
2525 }
2526}
2527
2528/// An iterator over the entries of a `HashTable` in arbitrary order.
2529/// The iterator element type is `&'a T`.
2530///
2531/// This `struct` is created by the [`iter`] method on [`HashTable`]. See its
2532/// documentation for more.
2533///
2534/// [`iter`]: HashTable::iter
2535pub struct Iter<'a, T> {
2536 inner: RawIter<T>,
2537 marker: PhantomData<&'a T>,
2538}
2539
2540impl<T> Default for Iter<'_, T> {
2541 #[cfg_attr(feature = "inline-more", inline)]
2542 fn default() -> Self {
2543 Iter {
2544 inner: Default::default(),
2545 marker: PhantomData,
2546 }
2547 }
2548}
2549
2550impl<'a, T> Iterator for Iter<'a, T> {
2551 type Item = &'a T;
2552
2553 fn next(&mut self) -> Option<Self::Item> {
2554 // Avoid `Option::map` because it bloats LLVM IR.
2555 match self.inner.next() {
2556 Some(bucket) => Some(unsafe { bucket.as_ref() }),
2557 None => None,
2558 }
2559 }
2560
2561 fn size_hint(&self) -> (usize, Option<usize>) {
2562 self.inner.size_hint()
2563 }
2564
2565 fn fold<B, F>(self, init: B, mut f: F) -> B
2566 where
2567 Self: Sized,
2568 F: FnMut(B, Self::Item) -> B,
2569 {
2570 self.inner
2571 .fold(init, |acc, bucket| unsafe { f(acc, bucket.as_ref()) })
2572 }
2573}
2574
2575impl<T> ExactSizeIterator for Iter<'_, T> {
2576 fn len(&self) -> usize {
2577 self.inner.len()
2578 }
2579}
2580
2581impl<T> FusedIterator for Iter<'_, T> {}
2582
2583// FIXME(#26925) Remove in favor of `#[derive(Clone)]`
2584impl<'a, T> Clone for Iter<'a, T> {
2585 #[cfg_attr(feature = "inline-more", inline)]
2586 fn clone(&self) -> Iter<'a, T> {
2587 Iter {
2588 inner: self.inner.clone(),
2589 marker: PhantomData,
2590 }
2591 }
2592}
2593
2594impl<T: fmt::Debug> fmt::Debug for Iter<'_, T> {
2595 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2596 f.debug_list().entries(self.clone()).finish()
2597 }
2598}
2599
2600/// A mutable iterator over the entries of a `HashTable` in arbitrary order.
2601/// The iterator element type is `&'a mut T`.
2602///
2603/// This `struct` is created by the [`iter_mut`] method on [`HashTable`]. See its
2604/// documentation for more.
2605///
2606/// [`iter_mut`]: HashTable::iter_mut
2607pub struct IterMut<'a, T> {
2608 inner: RawIter<T>,
2609 marker: PhantomData<&'a mut T>,
2610}
2611impl<'a, T> IterMut<'a, T> {
2612 /// Returns a iterator of references over the remaining items.
2613 #[cfg_attr(feature = "inline-more", inline)]
2614 pub fn iter(&self) -> Iter<'_, T> {
2615 Iter {
2616 inner: self.inner.clone(),
2617 marker: PhantomData,
2618 }
2619 }
2620}
2621
2622impl<T> Default for IterMut<'_, T> {
2623 #[cfg_attr(feature = "inline-more", inline)]
2624 fn default() -> Self {
2625 IterMut {
2626 inner: Default::default(),
2627 marker: PhantomData,
2628 }
2629 }
2630}
2631impl<'a, T> Iterator for IterMut<'a, T> {
2632 type Item = &'a mut T;
2633
2634 fn next(&mut self) -> Option<Self::Item> {
2635 // Avoid `Option::map` because it bloats LLVM IR.
2636 match self.inner.next() {
2637 Some(bucket) => Some(unsafe { bucket.as_mut() }),
2638 None => None,
2639 }
2640 }
2641
2642 fn size_hint(&self) -> (usize, Option<usize>) {
2643 self.inner.size_hint()
2644 }
2645
2646 fn fold<B, F>(self, init: B, mut f: F) -> B
2647 where
2648 Self: Sized,
2649 F: FnMut(B, Self::Item) -> B,
2650 {
2651 self.inner
2652 .fold(init, |acc, bucket| unsafe { f(acc, bucket.as_mut()) })
2653 }
2654}
2655
2656impl<T> ExactSizeIterator for IterMut<'_, T> {
2657 fn len(&self) -> usize {
2658 self.inner.len()
2659 }
2660}
2661
2662impl<T> FusedIterator for IterMut<'_, T> {}
2663
2664impl<T> fmt::Debug for IterMut<'_, T>
2665where
2666 T: fmt::Debug,
2667{
2668 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2669 f.debug_list().entries(self.iter()).finish()
2670 }
2671}
2672
2673/// An unsafe iterator over the entries of a `HashTable` in arbitrary order.
2674/// The iterator element type is `NonNull<T>`.
2675///
2676/// This `struct` is created by the [`unsafe_iter`] method on [`HashTable`].
2677///
2678/// This is used for implementations of iterators with "mixed" mutability on
2679/// the iterated elements. For example, a mutable iterator for a map may return
2680/// an immutable key alongside a mutable value, even though these are both
2681/// stored inside the table.
2682///
2683/// If you have no idea what any of this means, you probably should be using
2684/// [`IterMut`] instead, as it does not have any safety requirements.
2685///
2686/// # Safety
2687///
2688/// In order to correctly use this iterator, it should be wrapped in a safe
2689/// iterator struct with the appropriate [`PhantomData`] marker to indicate the
2690/// correct [variance].
2691///
2692/// For example, below is a simplified [`hash_map::IterMut`] implementation
2693/// that correctly returns a [covariant] key, and an [invariant] value:
2694///
2695/// [variance]: https://doc.rust-lang.org/stable/reference/subtyping.html#r-subtyping.variance
2696/// [covariant]: https://doc.rust-lang.org/stable/reference/subtyping.html#r-subtyping.variance.covariant
2697/// [invariant]: https://doc.rust-lang.org/stable/reference/subtyping.html#r-subtyping.variance.invariant
2698/// [`hash_map::IterMut`]: crate::hash_map::IterMut
2699/// [`unsafe_iter`]: HashTable::unsafe_iter
2700///
2701/// ```rust
2702/// use core::marker::PhantomData;
2703/// use hashbrown::hash_table;
2704///
2705/// pub struct IterMut<'a, K, V> {
2706/// inner: hash_table::UnsafeIter<'a, (K, V)>,
2707/// // Covariant over keys, invariant over values
2708/// marker: PhantomData<(&'a K, &'a mut V)>,
2709/// }
2710/// impl<'a, K, V> Iterator for IterMut<'a, K, V> {
2711/// // Immutable keys, mutable values
2712/// type Item = (&'a K, &'a mut V);
2713///
2714/// fn next(&mut self) -> Option<Self::Item> {
2715/// // SAFETY: The lifetime of the dereferenced pointer is derived from
2716/// // the lifetime of its iterator, ensuring that it's always valid.
2717/// // Additionally, we match the mutability in `self.marker` to ensure
2718/// // the correct variance.
2719/// let &mut (ref key, ref mut val) = unsafe { self.inner.next()?.as_mut() };
2720/// Some((key, val))
2721/// }
2722/// }
2723/// ```
2724pub struct UnsafeIter<'a, T> {
2725 inner: RawIter<T>,
2726 marker: PhantomData<&'a ()>,
2727}
2728impl<'a, T> UnsafeIter<'a, T> {
2729 /// Returns a iterator of references over the remaining items.
2730 #[cfg_attr(feature = "inline-more", inline)]
2731 pub fn iter(&self) -> Iter<'_, T> {
2732 Iter {
2733 inner: self.inner.clone(),
2734 marker: PhantomData,
2735 }
2736 }
2737}
2738
2739impl<T> Default for UnsafeIter<'_, T> {
2740 #[cfg_attr(feature = "inline-more", inline)]
2741 fn default() -> Self {
2742 UnsafeIter {
2743 inner: Default::default(),
2744 marker: PhantomData,
2745 }
2746 }
2747}
2748impl<'a, T> Iterator for UnsafeIter<'a, T> {
2749 type Item = NonNull<T>;
2750
2751 fn next(&mut self) -> Option<Self::Item> {
2752 // Avoid `Option::map` because it bloats LLVM IR.
2753 match self.inner.next() {
2754 Some(bucket) => Some(unsafe { NonNull::new_unchecked(bucket.as_ptr()) }),
2755 None => None,
2756 }
2757 }
2758
2759 fn size_hint(&self) -> (usize, Option<usize>) {
2760 self.inner.size_hint()
2761 }
2762
2763 fn fold<B, F>(self, init: B, mut f: F) -> B
2764 where
2765 Self: Sized,
2766 F: FnMut(B, Self::Item) -> B,
2767 {
2768 self.inner.fold(init, |acc, bucket| unsafe {
2769 f(acc, NonNull::new_unchecked(bucket.as_ptr()))
2770 })
2771 }
2772}
2773
2774impl<T> ExactSizeIterator for UnsafeIter<'_, T> {
2775 fn len(&self) -> usize {
2776 self.inner.len()
2777 }
2778}
2779
2780impl<T> FusedIterator for UnsafeIter<'_, T> {}
2781
2782impl<T> fmt::Debug for UnsafeIter<'_, T>
2783where
2784 T: fmt::Debug,
2785{
2786 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2787 f.debug_list().entries(self.iter()).finish()
2788 }
2789}
2790
2791/// An iterator producing the `usize` indices of all occupied buckets,
2792/// within the range `0..table.num_buckets()`.
2793///
2794/// The order in which the iterator yields indices is unspecified
2795/// and may change in the future.
2796///
2797/// This `struct` is created by the [`HashTable::iter_buckets`] method. See its
2798/// documentation for more.
2799pub struct IterBuckets<'a, T> {
2800 inner: FullBucketsIndices,
2801 marker: PhantomData<&'a T>,
2802}
2803
2804impl<T> Clone for IterBuckets<'_, T> {
2805 #[inline]
2806 fn clone(&self) -> Self {
2807 Self {
2808 inner: self.inner.clone(),
2809 marker: PhantomData,
2810 }
2811 }
2812}
2813
2814impl<T> Default for IterBuckets<'_, T> {
2815 #[inline]
2816 fn default() -> Self {
2817 Self {
2818 inner: Default::default(),
2819 marker: PhantomData,
2820 }
2821 }
2822}
2823
2824impl<T> Iterator for IterBuckets<'_, T> {
2825 type Item = usize;
2826
2827 #[inline]
2828 fn next(&mut self) -> Option<usize> {
2829 self.inner.next()
2830 }
2831
2832 #[inline]
2833 fn size_hint(&self) -> (usize, Option<usize>) {
2834 self.inner.size_hint()
2835 }
2836}
2837
2838impl<T> ExactSizeIterator for IterBuckets<'_, T> {
2839 #[inline]
2840 fn len(&self) -> usize {
2841 self.inner.len()
2842 }
2843}
2844
2845impl<T> FusedIterator for IterBuckets<'_, T> {}
2846
2847impl<T> fmt::Debug for IterBuckets<'_, T> {
2848 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2849 f.debug_list().entries(self.clone()).finish()
2850 }
2851}
2852
2853/// An iterator over the entries of a `HashTable` that could match a given hash.
2854/// The iterator element type is `&'a T`.
2855///
2856/// This `struct` is created by the [`iter_hash`] method on [`HashTable`]. See its
2857/// documentation for more.
2858///
2859/// [`iter_hash`]: HashTable::iter_hash
2860pub struct IterHash<'a, T> {
2861 inner: RawIterHash<T>,
2862 marker: PhantomData<&'a T>,
2863}
2864
2865impl<T> Default for IterHash<'_, T> {
2866 #[cfg_attr(feature = "inline-more", inline)]
2867 fn default() -> Self {
2868 IterHash {
2869 inner: Default::default(),
2870 marker: PhantomData,
2871 }
2872 }
2873}
2874
2875impl<'a, T> Iterator for IterHash<'a, T> {
2876 type Item = &'a T;
2877
2878 fn next(&mut self) -> Option<Self::Item> {
2879 // Avoid `Option::map` because it bloats LLVM IR.
2880 match self.inner.next() {
2881 Some(bucket) => Some(unsafe { bucket.as_ref() }),
2882 None => None,
2883 }
2884 }
2885
2886 fn fold<B, F>(self, init: B, mut f: F) -> B
2887 where
2888 Self: Sized,
2889 F: FnMut(B, Self::Item) -> B,
2890 {
2891 self.inner
2892 .fold(init, |acc, bucket| unsafe { f(acc, bucket.as_ref()) })
2893 }
2894}
2895
2896impl<T> FusedIterator for IterHash<'_, T> {}
2897
2898// FIXME(#26925) Remove in favor of `#[derive(Clone)]`
2899impl<'a, T> Clone for IterHash<'a, T> {
2900 #[cfg_attr(feature = "inline-more", inline)]
2901 fn clone(&self) -> IterHash<'a, T> {
2902 IterHash {
2903 inner: self.inner.clone(),
2904 marker: PhantomData,
2905 }
2906 }
2907}
2908
2909impl<T> fmt::Debug for IterHash<'_, T>
2910where
2911 T: fmt::Debug,
2912{
2913 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2914 f.debug_list().entries(self.clone()).finish()
2915 }
2916}
2917
2918/// A mutable iterator over the entries of a `HashTable` that could match a given hash.
2919/// The iterator element type is `&'a mut T`.
2920///
2921/// This `struct` is created by the [`iter_hash_mut`] method on [`HashTable`]. See its
2922/// documentation for more.
2923///
2924/// [`iter_hash_mut`]: HashTable::iter_hash_mut
2925pub struct IterHashMut<'a, T> {
2926 inner: RawIterHash<T>,
2927 marker: PhantomData<&'a mut T>,
2928}
2929
2930impl<T> Default for IterHashMut<'_, T> {
2931 #[cfg_attr(feature = "inline-more", inline)]
2932 fn default() -> Self {
2933 IterHashMut {
2934 inner: Default::default(),
2935 marker: PhantomData,
2936 }
2937 }
2938}
2939
2940impl<'a, T> Iterator for IterHashMut<'a, T> {
2941 type Item = &'a mut T;
2942
2943 fn next(&mut self) -> Option<Self::Item> {
2944 // Avoid `Option::map` because it bloats LLVM IR.
2945 match self.inner.next() {
2946 Some(bucket) => Some(unsafe { bucket.as_mut() }),
2947 None => None,
2948 }
2949 }
2950
2951 fn fold<B, F>(self, init: B, mut f: F) -> B
2952 where
2953 Self: Sized,
2954 F: FnMut(B, Self::Item) -> B,
2955 {
2956 self.inner
2957 .fold(init, |acc, bucket| unsafe { f(acc, bucket.as_mut()) })
2958 }
2959}
2960
2961impl<T> FusedIterator for IterHashMut<'_, T> {}
2962
2963impl<T> fmt::Debug for IterHashMut<'_, T>
2964where
2965 T: fmt::Debug,
2966{
2967 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2968 f.debug_list()
2969 .entries(IterHash {
2970 inner: self.inner.clone(),
2971 marker: PhantomData,
2972 })
2973 .finish()
2974 }
2975}
2976
2977/// An iterator producing the `usize` indices of all buckets which may match a hash.
2978///
2979/// This `struct` is created by the [`HashTable::iter_hash_buckets`] method. See its
2980/// documentation for more.
2981pub struct IterHashBuckets<'a, T> {
2982 inner: RawIterHashIndices,
2983 marker: PhantomData<&'a T>,
2984}
2985
2986impl<T> Clone for IterHashBuckets<'_, T> {
2987 #[inline]
2988 fn clone(&self) -> Self {
2989 Self {
2990 inner: self.inner.clone(),
2991 marker: PhantomData,
2992 }
2993 }
2994}
2995
2996impl<T> Default for IterHashBuckets<'_, T> {
2997 #[inline]
2998 fn default() -> Self {
2999 Self {
3000 inner: Default::default(),
3001 marker: PhantomData,
3002 }
3003 }
3004}
3005
3006impl<T> Iterator for IterHashBuckets<'_, T> {
3007 type Item = usize;
3008
3009 #[inline]
3010 fn next(&mut self) -> Option<Self::Item> {
3011 self.inner.next()
3012 }
3013}
3014
3015impl<T> FusedIterator for IterHashBuckets<'_, T> {}
3016
3017impl<T> fmt::Debug for IterHashBuckets<'_, T> {
3018 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3019 f.debug_list().entries(self.clone()).finish()
3020 }
3021}
3022
3023/// An owning iterator over the entries of a `HashTable` in arbitrary order.
3024/// The iterator element type is `T`.
3025///
3026/// This `struct` is created by the [`into_iter`] method on [`HashTable`]
3027/// (provided by the [`IntoIterator`] trait). See its documentation for more.
3028/// The table cannot be used after calling that method.
3029///
3030/// [`into_iter`]: HashTable::into_iter
3031pub struct IntoIter<T, A = Global>
3032where
3033 A: Allocator,
3034{
3035 inner: RawIntoIter<T, A>,
3036}
3037impl<T, A> IntoIter<T, A>
3038where
3039 A: Allocator,
3040{
3041 /// Returns a iterator of references over the remaining items.
3042 #[cfg_attr(feature = "inline-more", inline)]
3043 pub fn iter(&self) -> Iter<'_, T> {
3044 Iter {
3045 inner: self.inner.iter(),
3046 marker: PhantomData,
3047 }
3048 }
3049}
3050
3051impl<T, A: Allocator> Default for IntoIter<T, A> {
3052 #[cfg_attr(feature = "inline-more", inline)]
3053 fn default() -> Self {
3054 IntoIter {
3055 inner: Default::default(),
3056 }
3057 }
3058}
3059
3060impl<T, A> Iterator for IntoIter<T, A>
3061where
3062 A: Allocator,
3063{
3064 type Item = T;
3065
3066 fn next(&mut self) -> Option<Self::Item> {
3067 self.inner.next()
3068 }
3069
3070 fn size_hint(&self) -> (usize, Option<usize>) {
3071 self.inner.size_hint()
3072 }
3073
3074 fn fold<B, F>(self, init: B, f: F) -> B
3075 where
3076 Self: Sized,
3077 F: FnMut(B, Self::Item) -> B,
3078 {
3079 self.inner.fold(init, f)
3080 }
3081}
3082
3083impl<T, A> ExactSizeIterator for IntoIter<T, A>
3084where
3085 A: Allocator,
3086{
3087 fn len(&self) -> usize {
3088 self.inner.len()
3089 }
3090}
3091
3092impl<T, A> FusedIterator for IntoIter<T, A> where A: Allocator {}
3093
3094impl<T, A> fmt::Debug for IntoIter<T, A>
3095where
3096 T: fmt::Debug,
3097 A: Allocator,
3098{
3099 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3100 f.debug_list().entries(self.iter()).finish()
3101 }
3102}
3103
3104/// A draining iterator over the items of a `HashTable`.
3105///
3106/// This `struct` is created by the [`drain`] method on [`HashTable`].
3107/// See its documentation for more.
3108///
3109/// [`drain`]: HashTable::drain
3110pub struct Drain<'a, T, A: Allocator = Global> {
3111 inner: RawDrain<'a, T, A>,
3112}
3113impl<'a, T, A: Allocator> Drain<'a, T, A> {
3114 /// Returns a iterator of references over the remaining items.
3115 #[cfg_attr(feature = "inline-more", inline)]
3116 pub fn iter(&self) -> Iter<'_, T> {
3117 Iter {
3118 inner: self.inner.iter(),
3119 marker: PhantomData,
3120 }
3121 }
3122}
3123
3124impl<T, A: Allocator> Iterator for Drain<'_, T, A> {
3125 type Item = T;
3126
3127 fn next(&mut self) -> Option<T> {
3128 self.inner.next()
3129 }
3130
3131 fn size_hint(&self) -> (usize, Option<usize>) {
3132 self.inner.size_hint()
3133 }
3134
3135 fn fold<B, F>(self, init: B, f: F) -> B
3136 where
3137 Self: Sized,
3138 F: FnMut(B, Self::Item) -> B,
3139 {
3140 self.inner.fold(init, f)
3141 }
3142}
3143
3144impl<T, A: Allocator> ExactSizeIterator for Drain<'_, T, A> {
3145 fn len(&self) -> usize {
3146 self.inner.len()
3147 }
3148}
3149
3150impl<T, A: Allocator> FusedIterator for Drain<'_, T, A> {}
3151
3152impl<T: fmt::Debug, A: Allocator> fmt::Debug for Drain<'_, T, A> {
3153 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3154 f.debug_list().entries(self.iter()).finish()
3155 }
3156}
3157
3158/// A draining iterator over entries of a `HashTable` which don't satisfy the predicate `f`.
3159///
3160/// This `struct` is created by [`HashTable::extract_if`]. See its
3161/// documentation for more.
3162#[must_use = "Iterators are lazy unless consumed"]
3163pub struct ExtractIf<'a, T, F, A: Allocator = Global> {
3164 f: F,
3165 inner: RawExtractIf<'a, T, A>,
3166}
3167
3168impl<T, F, A: Allocator> Iterator for ExtractIf<'_, T, F, A>
3169where
3170 F: FnMut(&mut T) -> bool,
3171{
3172 type Item = T;
3173
3174 #[inline]
3175 fn next(&mut self) -> Option<Self::Item> {
3176 self.inner.next(|val| (self.f)(val))
3177 }
3178
3179 #[inline]
3180 fn size_hint(&self) -> (usize, Option<usize>) {
3181 (0, self.inner.iter.size_hint().1)
3182 }
3183}
3184
3185impl<T, F, A: Allocator> FusedIterator for ExtractIf<'_, T, F, A> where F: FnMut(&mut T) -> bool {}
3186
3187#[cfg(test)]
3188mod tests {
3189 use super::HashTable;
3190
3191 #[test]
3192 fn test_allocation_info() {
3193 assert_eq!(HashTable::<()>::new().allocation_size(), 0);
3194 assert_eq!(HashTable::<u32>::new().allocation_size(), 0);
3195 assert!(HashTable::<u32>::with_capacity(1).allocation_size() > core::mem::size_of::<u32>());
3196 }
3197}