hashbrown/
table.rs

1use core::{fmt, iter::FusedIterator, marker::PhantomData};
2
3use crate::{
4    raw::{
5        Allocator, Bucket, Global, InsertSlot, RawDrain, RawExtractIf, RawIntoIter, RawIter,
6        RawIterHash, RawTable,
7    },
8    TryReserveError,
9};
10
11/// Low-level hash table with explicit hashing.
12///
13/// The primary use case for this type over [`HashMap`] or [`HashSet`] is to
14/// support types that do not implement the [`Hash`] and [`Eq`] traits, but
15/// instead require additional data not contained in the key itself to compute a
16/// hash and compare two elements for equality.
17///
18/// Examples of when this can be useful include:
19/// - An `IndexMap` implementation where indices into a `Vec` are stored as
20///   elements in a `HashTable<usize>`. Hashing and comparing the elements
21///   requires indexing the associated `Vec` to get the actual value referred to
22///   by the index.
23/// - Avoiding re-computing a hash when it is already known.
24/// - Mutating the key of an element in a way that doesn't affect its hash.
25///
26/// To achieve this, `HashTable` methods that search for an element in the table
27/// require a hash value and equality function to be explicitly passed in as
28/// arguments. The method will then iterate over the elements with the given
29/// hash and call the equality function on each of them, until a match is found.
30///
31/// In most cases, a `HashTable` will not be exposed directly in an API. It will
32/// instead be wrapped in a helper type which handles the work of calculating
33/// hash values and comparing elements.
34///
35/// Due to its low-level nature, this type provides fewer guarantees than
36/// [`HashMap`] and [`HashSet`]. Specifically, the API allows you to shoot
37/// yourself in the foot by having multiple elements with identical keys in the
38/// table. The table itself will still function correctly and lookups will
39/// arbitrarily return one of the matching elements. However you should avoid
40/// doing this because it changes the runtime of hash table operations from
41/// `O(1)` to `O(k)` where `k` is the number of duplicate entries.
42///
43/// [`HashMap`]: super::HashMap
44/// [`HashSet`]: super::HashSet
45/// [`Eq`]: https://doc.rust-lang.org/std/cmp/trait.Eq.html
46/// [`Hash`]: https://doc.rust-lang.org/std/hash/trait.Hash.html
47pub struct HashTable<T, A = Global>
48where
49    A: Allocator,
50{
51    pub(crate) raw: RawTable<T, A>,
52}
53
54impl<T> HashTable<T, Global> {
55    /// Creates an empty `HashTable`.
56    ///
57    /// The hash table is initially created with a capacity of 0, so it will not allocate until it
58    /// is first inserted into.
59    ///
60    /// # Examples
61    ///
62    /// ```
63    /// use hashbrown::HashTable;
64    /// let mut table: HashTable<&str> = HashTable::new();
65    /// assert_eq!(table.len(), 0);
66    /// assert_eq!(table.capacity(), 0);
67    /// ```
68    pub const fn new() -> Self {
69        Self {
70            raw: RawTable::new(),
71        }
72    }
73
74    /// Creates an empty `HashTable` with the specified capacity.
75    ///
76    /// The hash table will be able to hold at least `capacity` elements without
77    /// reallocating. If `capacity` is 0, the hash table will not allocate.
78    ///
79    /// # Examples
80    ///
81    /// ```
82    /// use hashbrown::HashTable;
83    /// let mut table: HashTable<&str> = HashTable::with_capacity(10);
84    /// assert_eq!(table.len(), 0);
85    /// assert!(table.capacity() >= 10);
86    /// ```
87    pub fn with_capacity(capacity: usize) -> Self {
88        Self {
89            raw: RawTable::with_capacity(capacity),
90        }
91    }
92}
93
94impl<T, A> HashTable<T, A>
95where
96    A: Allocator,
97{
98    /// Creates an empty `HashTable` using the given allocator.
99    ///
100    /// The hash table is initially created with a capacity of 0, so it will not allocate until it
101    /// is first inserted into.
102    ///
103    /// # Examples
104    ///
105    /// ```
106    /// # #[cfg(feature = "nightly")]
107    /// # fn test() {
108    /// use bumpalo::Bump;
109    /// use hashbrown::{HashTable, DefaultHashBuilder};
110    /// use std::hash::BuildHasher;
111    ///
112    /// let bump = Bump::new();
113    /// let mut table = HashTable::new_in(&bump);
114    /// let hasher = DefaultHashBuilder::default();
115    /// let hasher = |val: &_| hasher.hash_one(val);
116    ///
117    /// // The created HashTable holds none elements
118    /// assert_eq!(table.len(), 0);
119    ///
120    /// // The created HashTable also doesn't allocate memory
121    /// assert_eq!(table.capacity(), 0);
122    ///
123    /// // Now we insert element inside created HashTable
124    /// table.insert_unique(hasher(&"One"), "One", hasher);
125    /// // We can see that the HashTable holds 1 element
126    /// assert_eq!(table.len(), 1);
127    /// // And it also allocates some capacity
128    /// assert!(table.capacity() > 1);
129    /// # }
130    /// # fn main() {
131    /// #     #[cfg(feature = "nightly")]
132    /// #     test()
133    /// # }
134    /// ```
135    pub const fn new_in(alloc: A) -> Self {
136        Self {
137            raw: RawTable::new_in(alloc),
138        }
139    }
140
141    /// Creates an empty `HashTable` with the specified capacity using the given allocator.
142    ///
143    /// The hash table will be able to hold at least `capacity` elements without
144    /// reallocating. If `capacity` is 0, the hash table will not allocate.
145    ///
146    /// # Examples
147    ///
148    /// ```
149    /// # #[cfg(feature = "nightly")]
150    /// # fn test() {
151    /// use bumpalo::Bump;
152    /// use hashbrown::{HashTable, DefaultHashBuilder};
153    /// use std::hash::BuildHasher;
154    ///
155    /// let bump = Bump::new();
156    /// let mut table = HashTable::with_capacity_in(5, &bump);
157    /// let hasher = DefaultHashBuilder::default();
158    /// let hasher = |val: &_| hasher.hash_one(val);
159    ///
160    /// // The created HashTable holds none elements
161    /// assert_eq!(table.len(), 0);
162    /// // But it can hold at least 5 elements without reallocating
163    /// let empty_map_capacity = table.capacity();
164    /// assert!(empty_map_capacity >= 5);
165    ///
166    /// // Now we insert some 5 elements inside created HashTable
167    /// table.insert_unique(hasher(&"One"), "One", hasher);
168    /// table.insert_unique(hasher(&"Two"), "Two", hasher);
169    /// table.insert_unique(hasher(&"Three"), "Three", hasher);
170    /// table.insert_unique(hasher(&"Four"), "Four", hasher);
171    /// table.insert_unique(hasher(&"Five"), "Five", hasher);
172    ///
173    /// // We can see that the HashTable holds 5 elements
174    /// assert_eq!(table.len(), 5);
175    /// // But its capacity isn't changed
176    /// assert_eq!(table.capacity(), empty_map_capacity)
177    /// # }
178    /// # fn main() {
179    /// #     #[cfg(feature = "nightly")]
180    /// #     test()
181    /// # }
182    /// ```
183    pub fn with_capacity_in(capacity: usize, alloc: A) -> Self {
184        Self {
185            raw: RawTable::with_capacity_in(capacity, alloc),
186        }
187    }
188
189    /// Returns a reference to the underlying allocator.
190    pub fn allocator(&self) -> &A {
191        self.raw.allocator()
192    }
193
194    /// Returns a reference to an entry in the table with the given hash and
195    /// which satisfies the equality function passed.
196    ///
197    /// This method will call `eq` for all entries with the given hash, but may
198    /// also call it for entries with a different hash. `eq` should only return
199    /// true for the desired entry, at which point the search is stopped.
200    ///
201    /// # Examples
202    ///
203    /// ```
204    /// # #[cfg(feature = "nightly")]
205    /// # fn test() {
206    /// use hashbrown::{HashTable, DefaultHashBuilder};
207    /// use std::hash::BuildHasher;
208    ///
209    /// let mut table = HashTable::new();
210    /// let hasher = DefaultHashBuilder::default();
211    /// let hasher = |val: &_| hasher.hash_one(val);
212    /// table.insert_unique(hasher(&1), 1, hasher);
213    /// table.insert_unique(hasher(&2), 2, hasher);
214    /// table.insert_unique(hasher(&3), 3, hasher);
215    /// assert_eq!(table.find(hasher(&2), |&val| val == 2), Some(&2));
216    /// assert_eq!(table.find(hasher(&4), |&val| val == 4), None);
217    /// # }
218    /// # fn main() {
219    /// #     #[cfg(feature = "nightly")]
220    /// #     test()
221    /// # }
222    /// ```
223    pub fn find(&self, hash: u64, eq: impl FnMut(&T) -> bool) -> Option<&T> {
224        self.raw.get(hash, eq)
225    }
226
227    /// Returns a mutable reference to an entry in the table with the given hash
228    /// and which satisfies the equality function passed.
229    ///
230    /// This method will call `eq` for all entries with the given hash, but may
231    /// also call it for entries with a different hash. `eq` should only return
232    /// true for the desired entry, at which point the search is stopped.
233    ///
234    /// When mutating an entry, you should ensure that it still retains the same
235    /// hash value as when it was inserted, otherwise lookups of that entry may
236    /// fail to find it.
237    ///
238    /// # Examples
239    ///
240    /// ```
241    /// # #[cfg(feature = "nightly")]
242    /// # fn test() {
243    /// use hashbrown::{HashTable, DefaultHashBuilder};
244    /// use std::hash::BuildHasher;
245    ///
246    /// let mut table = HashTable::new();
247    /// let hasher = DefaultHashBuilder::default();
248    /// let hasher = |val: &_| hasher.hash_one(val);
249    /// table.insert_unique(hasher(&1), (1, "a"), |val| hasher(&val.0));
250    /// if let Some(val) = table.find_mut(hasher(&1), |val| val.0 == 1) {
251    ///     val.1 = "b";
252    /// }
253    /// assert_eq!(table.find(hasher(&1), |val| val.0 == 1), Some(&(1, "b")));
254    /// assert_eq!(table.find(hasher(&2), |val| val.0 == 2), None);
255    /// # }
256    /// # fn main() {
257    /// #     #[cfg(feature = "nightly")]
258    /// #     test()
259    /// # }
260    /// ```
261    pub fn find_mut(&mut self, hash: u64, eq: impl FnMut(&T) -> bool) -> Option<&mut T> {
262        self.raw.get_mut(hash, eq)
263    }
264
265    /// Returns an `OccupiedEntry` for an entry in the table with the given hash
266    /// and which satisfies the equality function passed.
267    ///
268    /// This can be used to remove the entry from the table. Call
269    /// [`HashTable::entry`] instead if you wish to insert an entry if the
270    /// lookup fails.
271    ///
272    /// This method will call `eq` for all entries with the given hash, but may
273    /// also call it for entries with a different hash. `eq` should only return
274    /// true for the desired entry, at which point the search is stopped.
275    ///
276    /// # Examples
277    ///
278    /// ```
279    /// # #[cfg(feature = "nightly")]
280    /// # fn test() {
281    /// use hashbrown::{HashTable, DefaultHashBuilder};
282    /// use std::hash::BuildHasher;
283    ///
284    /// let mut table = HashTable::new();
285    /// let hasher = DefaultHashBuilder::default();
286    /// let hasher = |val: &_| hasher.hash_one(val);
287    /// table.insert_unique(hasher(&1), (1, "a"), |val| hasher(&val.0));
288    /// if let Ok(entry) = table.find_entry(hasher(&1), |val| val.0 == 1) {
289    ///     entry.remove();
290    /// }
291    /// assert_eq!(table.find(hasher(&1), |val| val.0 == 1), None);
292    /// # }
293    /// # fn main() {
294    /// #     #[cfg(feature = "nightly")]
295    /// #     test()
296    /// # }
297    /// ```
298    #[cfg_attr(feature = "inline-more", inline)]
299    pub fn find_entry(
300        &mut self,
301        hash: u64,
302        eq: impl FnMut(&T) -> bool,
303    ) -> Result<OccupiedEntry<'_, T, A>, AbsentEntry<'_, T, A>> {
304        match self.raw.find(hash, eq) {
305            Some(bucket) => Ok(OccupiedEntry {
306                hash,
307                bucket,
308                table: self,
309            }),
310            None => Err(AbsentEntry { table: self }),
311        }
312    }
313
314    /// Returns an `Entry` for an entry in the table with the given hash
315    /// and which satisfies the equality function passed.
316    ///
317    /// This can be used to remove the entry from the table, or insert a new
318    /// entry with the given hash if one doesn't already exist.
319    ///
320    /// This method will call `eq` for all entries with the given hash, but may
321    /// also call it for entries with a different hash. `eq` should only return
322    /// true for the desired entry, at which point the search is stopped.
323    ///
324    /// This method may grow the table in preparation for an insertion. Call
325    /// [`HashTable::find_entry`] if this is undesirable.
326    ///
327    /// `hasher` is called if entries need to be moved or copied to a new table.
328    /// This must return the same hash value that each entry was inserted with.
329    ///
330    /// # Examples
331    ///
332    /// ```
333    /// # #[cfg(feature = "nightly")]
334    /// # fn test() {
335    /// use hashbrown::hash_table::Entry;
336    /// use hashbrown::{HashTable, DefaultHashBuilder};
337    /// use std::hash::BuildHasher;
338    ///
339    /// let mut table = HashTable::new();
340    /// let hasher = DefaultHashBuilder::default();
341    /// let hasher = |val: &_| hasher.hash_one(val);
342    /// table.insert_unique(hasher(&1), (1, "a"), |val| hasher(&val.0));
343    /// if let Entry::Occupied(entry) = table.entry(hasher(&1), |val| val.0 == 1, |val| hasher(&val.0))
344    /// {
345    ///     entry.remove();
346    /// }
347    /// if let Entry::Vacant(entry) = table.entry(hasher(&2), |val| val.0 == 2, |val| hasher(&val.0)) {
348    ///     entry.insert((2, "b"));
349    /// }
350    /// assert_eq!(table.find(hasher(&1), |val| val.0 == 1), None);
351    /// assert_eq!(table.find(hasher(&2), |val| val.0 == 2), Some(&(2, "b")));
352    /// # }
353    /// # fn main() {
354    /// #     #[cfg(feature = "nightly")]
355    /// #     test()
356    /// # }
357    /// ```
358    #[cfg_attr(feature = "inline-more", inline)]
359    pub fn entry(
360        &mut self,
361        hash: u64,
362        eq: impl FnMut(&T) -> bool,
363        hasher: impl Fn(&T) -> u64,
364    ) -> Entry<'_, T, A> {
365        match self.raw.find_or_find_insert_slot(hash, eq, hasher) {
366            Ok(bucket) => Entry::Occupied(OccupiedEntry {
367                hash,
368                bucket,
369                table: self,
370            }),
371            Err(insert_slot) => Entry::Vacant(VacantEntry {
372                hash,
373                insert_slot,
374                table: self,
375            }),
376        }
377    }
378
379    /// Inserts an element into the `HashTable` with the given hash value, but
380    /// without checking whether an equivalent element already exists within the
381    /// table.
382    ///
383    /// `hasher` is called if entries need to be moved or copied to a new table.
384    /// This must return the same hash value that each entry was inserted with.
385    ///
386    /// # Examples
387    ///
388    /// ```
389    /// # #[cfg(feature = "nightly")]
390    /// # fn test() {
391    /// use hashbrown::{HashTable, DefaultHashBuilder};
392    /// use std::hash::BuildHasher;
393    ///
394    /// let mut v = HashTable::new();
395    /// let hasher = DefaultHashBuilder::default();
396    /// let hasher = |val: &_| hasher.hash_one(val);
397    /// v.insert_unique(hasher(&1), 1, hasher);
398    /// # }
399    /// # fn main() {
400    /// #     #[cfg(feature = "nightly")]
401    /// #     test()
402    /// # }
403    /// ```
404    pub fn insert_unique(
405        &mut self,
406        hash: u64,
407        value: T,
408        hasher: impl Fn(&T) -> u64,
409    ) -> OccupiedEntry<'_, T, A> {
410        let bucket = self.raw.insert(hash, value, hasher);
411        OccupiedEntry {
412            hash,
413            bucket,
414            table: self,
415        }
416    }
417
418    /// Clears the table, removing all values.
419    ///
420    /// # Examples
421    ///
422    /// ```
423    /// # #[cfg(feature = "nightly")]
424    /// # fn test() {
425    /// use hashbrown::{HashTable, DefaultHashBuilder};
426    /// use std::hash::BuildHasher;
427    ///
428    /// let mut v = HashTable::new();
429    /// let hasher = DefaultHashBuilder::default();
430    /// let hasher = |val: &_| hasher.hash_one(val);
431    /// v.insert_unique(hasher(&1), 1, hasher);
432    /// v.clear();
433    /// assert!(v.is_empty());
434    /// # }
435    /// # fn main() {
436    /// #     #[cfg(feature = "nightly")]
437    /// #     test()
438    /// # }
439    /// ```
440    pub fn clear(&mut self) {
441        self.raw.clear();
442    }
443
444    /// Shrinks the capacity of the table as much as possible. It will drop
445    /// down as much as possible while maintaining the internal rules
446    /// and possibly leaving some space in accordance with the resize policy.
447    ///
448    /// `hasher` is called if entries need to be moved or copied to a new table.
449    /// This must return the same hash value that each entry was inserted with.
450    ///
451    /// # Examples
452    ///
453    /// ```
454    /// # #[cfg(feature = "nightly")]
455    /// # fn test() {
456    /// use hashbrown::{HashTable, DefaultHashBuilder};
457    /// use std::hash::BuildHasher;
458    ///
459    /// let mut table = HashTable::with_capacity(100);
460    /// let hasher = DefaultHashBuilder::default();
461    /// let hasher = |val: &_| hasher.hash_one(val);
462    /// table.insert_unique(hasher(&1), 1, hasher);
463    /// table.insert_unique(hasher(&2), 2, hasher);
464    /// assert!(table.capacity() >= 100);
465    /// table.shrink_to_fit(hasher);
466    /// assert!(table.capacity() >= 2);
467    /// # }
468    /// # fn main() {
469    /// #     #[cfg(feature = "nightly")]
470    /// #     test()
471    /// # }
472    /// ```
473    pub fn shrink_to_fit(&mut self, hasher: impl Fn(&T) -> u64) {
474        self.raw.shrink_to(self.len(), hasher)
475    }
476
477    /// Shrinks the capacity of the table with a lower limit. It will drop
478    /// down no lower than the supplied limit while maintaining the internal rules
479    /// and possibly leaving some space in accordance with the resize policy.
480    ///
481    /// `hasher` is called if entries need to be moved or copied to a new table.
482    /// This must return the same hash value that each entry was inserted with.
483    ///
484    /// Panics if the current capacity is smaller than the supplied
485    /// minimum capacity.
486    ///
487    /// # Examples
488    ///
489    /// ```
490    /// # #[cfg(feature = "nightly")]
491    /// # fn test() {
492    /// use hashbrown::{HashTable, DefaultHashBuilder};
493    /// use std::hash::BuildHasher;
494    ///
495    /// let mut table = HashTable::with_capacity(100);
496    /// let hasher = DefaultHashBuilder::default();
497    /// let hasher = |val: &_| hasher.hash_one(val);
498    /// table.insert_unique(hasher(&1), 1, hasher);
499    /// table.insert_unique(hasher(&2), 2, hasher);
500    /// assert!(table.capacity() >= 100);
501    /// table.shrink_to(10, hasher);
502    /// assert!(table.capacity() >= 10);
503    /// table.shrink_to(0, hasher);
504    /// assert!(table.capacity() >= 2);
505    /// # }
506    /// # fn main() {
507    /// #     #[cfg(feature = "nightly")]
508    /// #     test()
509    /// # }
510    /// ```
511    pub fn shrink_to(&mut self, min_capacity: usize, hasher: impl Fn(&T) -> u64) {
512        self.raw.shrink_to(min_capacity, hasher);
513    }
514
515    /// Reserves capacity for at least `additional` more elements to be inserted
516    /// in the `HashTable`. The collection may reserve more space to avoid
517    /// frequent reallocations.
518    ///
519    /// `hasher` is called if entries need to be moved or copied to a new table.
520    /// This must return the same hash value that each entry was inserted with.
521    ///
522    /// # Panics
523    ///
524    /// Panics if the new capacity exceeds [`isize::MAX`] bytes and [`abort`] the program
525    /// in case of allocation error. Use [`try_reserve`](HashTable::try_reserve) instead
526    /// if you want to handle memory allocation failure.
527    ///
528    /// [`isize::MAX`]: https://doc.rust-lang.org/std/primitive.isize.html
529    /// [`abort`]: https://doc.rust-lang.org/alloc/alloc/fn.handle_alloc_error.html
530    ///
531    /// # Examples
532    ///
533    /// ```
534    /// # #[cfg(feature = "nightly")]
535    /// # fn test() {
536    /// use hashbrown::{HashTable, DefaultHashBuilder};
537    /// use std::hash::BuildHasher;
538    ///
539    /// let mut table: HashTable<i32> = HashTable::new();
540    /// let hasher = DefaultHashBuilder::default();
541    /// let hasher = |val: &_| hasher.hash_one(val);
542    /// table.reserve(10, hasher);
543    /// assert!(table.capacity() >= 10);
544    /// # }
545    /// # fn main() {
546    /// #     #[cfg(feature = "nightly")]
547    /// #     test()
548    /// # }
549    /// ```
550    pub fn reserve(&mut self, additional: usize, hasher: impl Fn(&T) -> u64) {
551        self.raw.reserve(additional, hasher)
552    }
553
554    /// Tries to reserve capacity for at least `additional` more elements to be inserted
555    /// in the given `HashTable`. The collection may reserve more space to avoid
556    /// frequent reallocations.
557    ///
558    /// `hasher` is called if entries need to be moved or copied to a new table.
559    /// This must return the same hash value that each entry was inserted with.
560    ///
561    /// # Errors
562    ///
563    /// If the capacity overflows, or the allocator reports a failure, then an error
564    /// is returned.
565    ///
566    /// # Examples
567    ///
568    /// ```
569    /// # #[cfg(feature = "nightly")]
570    /// # fn test() {
571    /// use hashbrown::{HashTable, DefaultHashBuilder};
572    /// use std::hash::BuildHasher;
573    ///
574    /// let mut table: HashTable<i32> = HashTable::new();
575    /// let hasher = DefaultHashBuilder::default();
576    /// let hasher = |val: &_| hasher.hash_one(val);
577    /// table
578    ///     .try_reserve(10, hasher)
579    ///     .expect("why is the test harness OOMing on 10 bytes?");
580    /// # }
581    /// # fn main() {
582    /// #     #[cfg(feature = "nightly")]
583    /// #     test()
584    /// # }
585    /// ```
586    pub fn try_reserve(
587        &mut self,
588        additional: usize,
589        hasher: impl Fn(&T) -> u64,
590    ) -> Result<(), TryReserveError> {
591        self.raw.try_reserve(additional, hasher)
592    }
593
594    /// Returns the number of elements the table can hold without reallocating.
595    ///
596    /// # Examples
597    ///
598    /// ```
599    /// use hashbrown::HashTable;
600    /// let table: HashTable<i32> = HashTable::with_capacity(100);
601    /// assert!(table.capacity() >= 100);
602    /// ```
603    pub fn capacity(&self) -> usize {
604        self.raw.capacity()
605    }
606
607    /// Returns the number of elements in the table.
608    ///
609    /// # Examples
610    ///
611    /// ```
612    /// # #[cfg(feature = "nightly")]
613    /// # fn test() {
614    /// use hashbrown::{HashTable, DefaultHashBuilder};
615    /// use std::hash::BuildHasher;
616    ///
617    /// let hasher = DefaultHashBuilder::default();
618    /// let hasher = |val: &_| hasher.hash_one(val);
619    /// let mut v = HashTable::new();
620    /// assert_eq!(v.len(), 0);
621    /// v.insert_unique(hasher(&1), 1, hasher);
622    /// assert_eq!(v.len(), 1);
623    /// # }
624    /// # fn main() {
625    /// #     #[cfg(feature = "nightly")]
626    /// #     test()
627    /// # }
628    /// ```
629    pub fn len(&self) -> usize {
630        self.raw.len()
631    }
632
633    /// Returns `true` if the set contains no elements.
634    ///
635    /// # Examples
636    ///
637    /// ```
638    /// # #[cfg(feature = "nightly")]
639    /// # fn test() {
640    /// use hashbrown::{HashTable, DefaultHashBuilder};
641    /// use std::hash::BuildHasher;
642    ///
643    /// let hasher = DefaultHashBuilder::default();
644    /// let hasher = |val: &_| hasher.hash_one(val);
645    /// let mut v = HashTable::new();
646    /// assert!(v.is_empty());
647    /// v.insert_unique(hasher(&1), 1, hasher);
648    /// assert!(!v.is_empty());
649    /// # }
650    /// # fn main() {
651    /// #     #[cfg(feature = "nightly")]
652    /// #     test()
653    /// # }
654    /// ```
655    pub fn is_empty(&self) -> bool {
656        self.raw.is_empty()
657    }
658
659    /// An iterator visiting all elements in arbitrary order.
660    /// The iterator element type is `&'a T`.
661    ///
662    /// # Examples
663    ///
664    /// ```
665    /// # #[cfg(feature = "nightly")]
666    /// # fn test() {
667    /// use hashbrown::{HashTable, DefaultHashBuilder};
668    /// use std::hash::BuildHasher;
669    ///
670    /// let mut table = HashTable::new();
671    /// let hasher = DefaultHashBuilder::default();
672    /// let hasher = |val: &_| hasher.hash_one(val);
673    /// table.insert_unique(hasher(&"a"), "b", hasher);
674    /// table.insert_unique(hasher(&"b"), "b", hasher);
675    ///
676    /// // Will print in an arbitrary order.
677    /// for x in table.iter() {
678    ///     println!("{}", x);
679    /// }
680    /// # }
681    /// # fn main() {
682    /// #     #[cfg(feature = "nightly")]
683    /// #     test()
684    /// # }
685    /// ```
686    pub fn iter(&self) -> Iter<'_, T> {
687        Iter {
688            inner: unsafe { self.raw.iter() },
689            marker: PhantomData,
690        }
691    }
692
693    /// An iterator visiting all elements in arbitrary order,
694    /// with mutable references to the elements.
695    /// The iterator element type is `&'a mut T`.
696    ///
697    /// # Examples
698    ///
699    /// ```
700    /// # #[cfg(feature = "nightly")]
701    /// # fn test() {
702    /// use hashbrown::{HashTable, DefaultHashBuilder};
703    /// use std::hash::BuildHasher;
704    ///
705    /// let mut table = HashTable::new();
706    /// let hasher = DefaultHashBuilder::default();
707    /// let hasher = |val: &_| hasher.hash_one(val);
708    /// table.insert_unique(hasher(&1), 1, hasher);
709    /// table.insert_unique(hasher(&2), 2, hasher);
710    /// table.insert_unique(hasher(&3), 3, hasher);
711    ///
712    /// // Update all values
713    /// for val in table.iter_mut() {
714    ///     *val *= 2;
715    /// }
716    ///
717    /// assert_eq!(table.len(), 3);
718    /// let mut vec: Vec<i32> = Vec::new();
719    ///
720    /// for val in &table {
721    ///     println!("val: {}", val);
722    ///     vec.push(*val);
723    /// }
724    ///
725    /// // The `Iter` iterator produces items in arbitrary order, so the
726    /// // items must be sorted to test them against a sorted array.
727    /// vec.sort_unstable();
728    /// assert_eq!(vec, [2, 4, 6]);
729    ///
730    /// assert_eq!(table.len(), 3);
731    /// # }
732    /// # fn main() {
733    /// #     #[cfg(feature = "nightly")]
734    /// #     test()
735    /// # }
736    /// ```
737    pub fn iter_mut(&mut self) -> IterMut<'_, T> {
738        IterMut {
739            inner: unsafe { self.raw.iter() },
740            marker: PhantomData,
741        }
742    }
743
744    /// An iterator visiting all elements which may match a hash.
745    /// The iterator element type is `&'a T`.
746    ///
747    /// This iterator may return elements from the table that have a hash value
748    /// different than the one provided. You should always validate the returned
749    /// values before using them.
750    ///
751    /// # Examples
752    ///
753    /// ```
754    /// # #[cfg(feature = "nightly")]
755    /// # fn test() {
756    /// use hashbrown::{HashTable, DefaultHashBuilder};
757    /// use std::hash::BuildHasher;
758    ///
759    /// let mut table = HashTable::new();
760    /// let hasher = DefaultHashBuilder::default();
761    /// let hasher = |val: &_| hasher.hash_one(val);
762    /// table.insert_unique(hasher(&"a"), "a", hasher);
763    /// table.insert_unique(hasher(&"a"), "b", hasher);
764    /// table.insert_unique(hasher(&"b"), "c", hasher);
765    ///
766    /// // Will print "a" and "b" (and possibly "c") in an arbitrary order.
767    /// for x in table.iter_hash(hasher(&"a")) {
768    ///     println!("{}", x);
769    /// }
770    /// # }
771    /// # fn main() {
772    /// #     #[cfg(feature = "nightly")]
773    /// #     test()
774    /// # }
775    /// ```
776    pub fn iter_hash(&self, hash: u64) -> IterHash<'_, T> {
777        IterHash {
778            inner: unsafe { self.raw.iter_hash(hash) },
779            marker: PhantomData,
780        }
781    }
782
783    /// A mutable iterator visiting all elements which may match a hash.
784    /// The iterator element type is `&'a mut T`.
785    ///
786    /// This iterator may return elements from the table that have a hash value
787    /// different than the one provided. You should always validate the returned
788    /// values before using them.
789    ///
790    /// # Examples
791    ///
792    /// ```
793    /// # #[cfg(feature = "nightly")]
794    /// # fn test() {
795    /// use hashbrown::{HashTable, DefaultHashBuilder};
796    /// use std::hash::BuildHasher;
797    ///
798    /// let mut table = HashTable::new();
799    /// let hasher = DefaultHashBuilder::default();
800    /// let hasher = |val: &_| hasher.hash_one(val);
801    /// table.insert_unique(hasher(&1), 2, hasher);
802    /// table.insert_unique(hasher(&1), 3, hasher);
803    /// table.insert_unique(hasher(&2), 5, hasher);
804    ///
805    /// // Update matching values
806    /// for val in table.iter_hash_mut(hasher(&1)) {
807    ///     *val *= 2;
808    /// }
809    ///
810    /// assert_eq!(table.len(), 3);
811    /// let mut vec: Vec<i32> = Vec::new();
812    ///
813    /// for val in &table {
814    ///     println!("val: {}", val);
815    ///     vec.push(*val);
816    /// }
817    ///
818    /// // The values will contain 4 and 6 and may contain either 5 or 10.
819    /// assert!(vec.contains(&4));
820    /// assert!(vec.contains(&6));
821    ///
822    /// assert_eq!(table.len(), 3);
823    /// # }
824    /// # fn main() {
825    /// #     #[cfg(feature = "nightly")]
826    /// #     test()
827    /// # }
828    /// ```
829    pub fn iter_hash_mut(&mut self, hash: u64) -> IterHashMut<'_, T> {
830        IterHashMut {
831            inner: unsafe { self.raw.iter_hash(hash) },
832            marker: PhantomData,
833        }
834    }
835
836    /// Retains only the elements specified by the predicate.
837    ///
838    /// In other words, remove all elements `e` such that `f(&e)` returns `false`.
839    ///
840    /// # Examples
841    ///
842    /// ```
843    /// # #[cfg(feature = "nightly")]
844    /// # fn test() {
845    /// use hashbrown::{HashTable, DefaultHashBuilder};
846    /// use std::hash::BuildHasher;
847    ///
848    /// let mut table = HashTable::new();
849    /// let hasher = DefaultHashBuilder::default();
850    /// let hasher = |val: &_| hasher.hash_one(val);
851    /// for x in 1..=6 {
852    ///     table.insert_unique(hasher(&x), x, hasher);
853    /// }
854    /// table.retain(|&mut x| x % 2 == 0);
855    /// assert_eq!(table.len(), 3);
856    /// # }
857    /// # fn main() {
858    /// #     #[cfg(feature = "nightly")]
859    /// #     test()
860    /// # }
861    /// ```
862    pub fn retain(&mut self, mut f: impl FnMut(&mut T) -> bool) {
863        // Here we only use `iter` as a temporary, preventing use-after-free
864        unsafe {
865            for item in self.raw.iter() {
866                if !f(item.as_mut()) {
867                    self.raw.erase(item);
868                }
869            }
870        }
871    }
872
873    /// Clears the set, returning all elements in an iterator.
874    ///
875    /// # Examples
876    ///
877    /// ```
878    /// # #[cfg(feature = "nightly")]
879    /// # fn test() {
880    /// use hashbrown::{HashTable, DefaultHashBuilder};
881    /// use std::hash::BuildHasher;
882    ///
883    /// let mut table = HashTable::new();
884    /// let hasher = DefaultHashBuilder::default();
885    /// let hasher = |val: &_| hasher.hash_one(val);
886    /// for x in 1..=3 {
887    ///     table.insert_unique(hasher(&x), x, hasher);
888    /// }
889    /// assert!(!table.is_empty());
890    ///
891    /// // print 1, 2, 3 in an arbitrary order
892    /// for i in table.drain() {
893    ///     println!("{}", i);
894    /// }
895    ///
896    /// assert!(table.is_empty());
897    /// # }
898    /// # fn main() {
899    /// #     #[cfg(feature = "nightly")]
900    /// #     test()
901    /// # }
902    /// ```
903    pub fn drain(&mut self) -> Drain<'_, T, A> {
904        Drain {
905            inner: self.raw.drain(),
906        }
907    }
908
909    /// Drains elements which are true under the given predicate,
910    /// and returns an iterator over the removed items.
911    ///
912    /// In other words, move all elements `e` such that `f(&e)` returns `true` out
913    /// into another iterator.
914    ///
915    /// If the returned `ExtractIf` is not exhausted, e.g. because it is dropped without iterating
916    /// or the iteration short-circuits, then the remaining elements will be retained.
917    /// Use [`retain()`] with a negated predicate if you do not need the returned iterator.
918    ///
919    /// [`retain()`]: HashTable::retain
920    ///
921    /// # Examples
922    ///
923    /// ```
924    /// # #[cfg(feature = "nightly")]
925    /// # fn test() {
926    /// use hashbrown::{HashTable, DefaultHashBuilder};
927    /// use std::hash::BuildHasher;
928    ///
929    /// let mut table = HashTable::new();
930    /// let hasher = DefaultHashBuilder::default();
931    /// let hasher = |val: &_| hasher.hash_one(val);
932    /// for x in 0..8 {
933    ///     table.insert_unique(hasher(&x), x, hasher);
934    /// }
935    /// let drained: Vec<i32> = table.extract_if(|&mut v| v % 2 == 0).collect();
936    ///
937    /// let mut evens = drained.into_iter().collect::<Vec<_>>();
938    /// let mut odds = table.into_iter().collect::<Vec<_>>();
939    /// evens.sort();
940    /// odds.sort();
941    ///
942    /// assert_eq!(evens, vec![0, 2, 4, 6]);
943    /// assert_eq!(odds, vec![1, 3, 5, 7]);
944    /// # }
945    /// # fn main() {
946    /// #     #[cfg(feature = "nightly")]
947    /// #     test()
948    /// # }
949    /// ```
950    pub fn extract_if<F>(&mut self, f: F) -> ExtractIf<'_, T, F, A>
951    where
952        F: FnMut(&mut T) -> bool,
953    {
954        ExtractIf {
955            f,
956            inner: RawExtractIf {
957                iter: unsafe { self.raw.iter() },
958                table: &mut self.raw,
959            },
960        }
961    }
962
963    /// Attempts to get mutable references to `N` values in the map at once.
964    ///
965    /// The `eq` argument should be a closure such that `eq(i, k)` returns true if `k` is equal to
966    /// the `i`th key to be looked up.
967    ///
968    /// Returns an array of length `N` with the results of each query. For soundness, at most one
969    /// mutable reference will be returned to any value. `None` will be used if the key is missing.
970    ///
971    /// # Panics
972    ///
973    /// Panics if any keys are overlapping.
974    ///
975    /// # Examples
976    ///
977    /// ```
978    /// # #[cfg(feature = "nightly")]
979    /// # fn test() {
980    /// use hashbrown::hash_table::Entry;
981    /// use hashbrown::{HashTable, DefaultHashBuilder};
982    /// use std::hash::BuildHasher;
983    ///
984    /// let mut libraries: HashTable<(&str, u32)> = HashTable::new();
985    /// let hasher = DefaultHashBuilder::default();
986    /// let hasher = |val: &_| hasher.hash_one(val);
987    /// for (k, v) in [
988    ///     ("Bodleian Library", 1602),
989    ///     ("Athenæum", 1807),
990    ///     ("Herzogin-Anna-Amalia-Bibliothek", 1691),
991    ///     ("Library of Congress", 1800),
992    /// ] {
993    ///     libraries.insert_unique(hasher(&k), (k, v), |(k, _)| hasher(&k));
994    /// }
995    ///
996    /// let keys = ["Athenæum", "Library of Congress"];
997    /// let got = libraries.get_many_mut(keys.map(|k| hasher(&k)), |i, val| keys[i] == val.0);
998    /// assert_eq!(
999    ///     got,
1000    ///     [Some(&mut ("Athenæum", 1807)), Some(&mut ("Library of Congress", 1800))],
1001    /// );
1002    ///
1003    /// // Missing keys result in None
1004    /// let keys = ["Athenæum", "New York Public Library"];
1005    /// let got = libraries.get_many_mut(keys.map(|k| hasher(&k)), |i, val| keys[i] == val.0);
1006    /// assert_eq!(got, [Some(&mut ("Athenæum", 1807)), None]);
1007    /// # }
1008    /// # fn main() {
1009    /// #     #[cfg(feature = "nightly")]
1010    /// #     test()
1011    /// # }
1012    /// ```
1013    ///
1014    /// ```should_panic
1015    /// # #[cfg(feature = "nightly")]
1016    /// # fn test() {
1017    /// # use hashbrown::{HashTable, DefaultHashBuilder};
1018    /// # use std::hash::BuildHasher;
1019    ///
1020    /// let mut libraries: HashTable<(&str, u32)> = HashTable::new();
1021    /// let hasher = DefaultHashBuilder::default();
1022    /// let hasher = |val: &_| hasher.hash_one(val);
1023    /// for (k, v) in [
1024    ///     ("Athenæum", 1807),
1025    ///     ("Library of Congress", 1800),
1026    /// ] {
1027    ///     libraries.insert_unique(hasher(&k), (k, v), |(k, _)| hasher(&k));
1028    /// }
1029    ///
1030    /// // Duplicate keys result in a panic!
1031    /// let keys = ["Athenæum", "Athenæum"];
1032    /// let got = libraries.get_many_mut(keys.map(|k| hasher(&k)), |i, val| keys[i] == val.0);
1033    /// # }
1034    /// # fn main() {
1035    /// #     #[cfg(feature = "nightly")]
1036    /// #     test();
1037    /// #     #[cfg(not(feature = "nightly"))]
1038    /// #     panic!();
1039    /// # }
1040    /// ```
1041    pub fn get_many_mut<const N: usize>(
1042        &mut self,
1043        hashes: [u64; N],
1044        eq: impl FnMut(usize, &T) -> bool,
1045    ) -> [Option<&'_ mut T>; N] {
1046        self.raw.get_many_mut(hashes, eq)
1047    }
1048
1049    /// Attempts to get mutable references to `N` values in the map at once, without validating that
1050    /// the values are unique.
1051    ///
1052    /// The `eq` argument should be a closure such that `eq(i, k)` returns true if `k` is equal to
1053    /// the `i`th key to be looked up.
1054    ///
1055    /// Returns an array of length `N` with the results of each query. `None` will be returned if
1056    /// any of the keys are missing.
1057    ///
1058    /// For a safe alternative see [`get_many_mut`](`HashTable::get_many_mut`).
1059    ///
1060    /// # Safety
1061    ///
1062    /// Calling this method with overlapping keys is *[undefined behavior]* even if the resulting
1063    /// references are not used.
1064    ///
1065    /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
1066    ///
1067    /// # Examples
1068    ///
1069    /// ```
1070    /// # #[cfg(feature = "nightly")]
1071    /// # fn test() {
1072    /// use hashbrown::hash_table::Entry;
1073    /// use hashbrown::{HashTable, DefaultHashBuilder};
1074    /// use std::hash::BuildHasher;
1075    ///
1076    /// let mut libraries: HashTable<(&str, u32)> = HashTable::new();
1077    /// let hasher = DefaultHashBuilder::default();
1078    /// let hasher = |val: &_| hasher.hash_one(val);
1079    /// for (k, v) in [
1080    ///     ("Bodleian Library", 1602),
1081    ///     ("Athenæum", 1807),
1082    ///     ("Herzogin-Anna-Amalia-Bibliothek", 1691),
1083    ///     ("Library of Congress", 1800),
1084    /// ] {
1085    ///     libraries.insert_unique(hasher(&k), (k, v), |(k, _)| hasher(&k));
1086    /// }
1087    ///
1088    /// let keys = ["Athenæum", "Library of Congress"];
1089    /// let got = libraries.get_many_mut(keys.map(|k| hasher(&k)), |i, val| keys[i] == val.0);
1090    /// assert_eq!(
1091    ///     got,
1092    ///     [Some(&mut ("Athenæum", 1807)), Some(&mut ("Library of Congress", 1800))],
1093    /// );
1094    ///
1095    /// // Missing keys result in None
1096    /// let keys = ["Athenæum", "New York Public Library"];
1097    /// let got = libraries.get_many_mut(keys.map(|k| hasher(&k)), |i, val| keys[i] == val.0);
1098    /// assert_eq!(got, [Some(&mut ("Athenæum", 1807)), None]);
1099    /// # }
1100    /// # fn main() {
1101    /// #     #[cfg(feature = "nightly")]
1102    /// #     test()
1103    /// # }
1104    /// ```
1105    pub unsafe fn get_many_unchecked_mut<const N: usize>(
1106        &mut self,
1107        hashes: [u64; N],
1108        eq: impl FnMut(usize, &T) -> bool,
1109    ) -> [Option<&'_ mut T>; N] {
1110        self.raw.get_many_unchecked_mut(hashes, eq)
1111    }
1112
1113    /// Returns the total amount of memory allocated internally by the hash
1114    /// table, in bytes.
1115    ///
1116    /// The returned number is informational only. It is intended to be
1117    /// primarily used for memory profiling.
1118    #[inline]
1119    pub fn allocation_size(&self) -> usize {
1120        self.raw.allocation_size()
1121    }
1122}
1123
1124impl<T, A> IntoIterator for HashTable<T, A>
1125where
1126    A: Allocator,
1127{
1128    type Item = T;
1129    type IntoIter = IntoIter<T, A>;
1130
1131    fn into_iter(self) -> IntoIter<T, A> {
1132        IntoIter {
1133            inner: self.raw.into_iter(),
1134        }
1135    }
1136}
1137
1138impl<'a, T, A> IntoIterator for &'a HashTable<T, A>
1139where
1140    A: Allocator,
1141{
1142    type Item = &'a T;
1143    type IntoIter = Iter<'a, T>;
1144
1145    fn into_iter(self) -> Iter<'a, T> {
1146        self.iter()
1147    }
1148}
1149
1150impl<'a, T, A> IntoIterator for &'a mut HashTable<T, A>
1151where
1152    A: Allocator,
1153{
1154    type Item = &'a mut T;
1155    type IntoIter = IterMut<'a, T>;
1156
1157    fn into_iter(self) -> IterMut<'a, T> {
1158        self.iter_mut()
1159    }
1160}
1161
1162impl<T, A> Default for HashTable<T, A>
1163where
1164    A: Allocator + Default,
1165{
1166    fn default() -> Self {
1167        Self {
1168            raw: Default::default(),
1169        }
1170    }
1171}
1172
1173impl<T, A> Clone for HashTable<T, A>
1174where
1175    T: Clone,
1176    A: Allocator + Clone,
1177{
1178    fn clone(&self) -> Self {
1179        Self {
1180            raw: self.raw.clone(),
1181        }
1182    }
1183}
1184
1185impl<T, A> fmt::Debug for HashTable<T, A>
1186where
1187    T: fmt::Debug,
1188    A: Allocator,
1189{
1190    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1191        f.debug_set().entries(self.iter()).finish()
1192    }
1193}
1194
1195/// A view into a single entry in a table, which may either be vacant or occupied.
1196///
1197/// This `enum` is constructed from the [`entry`] method on [`HashTable`].
1198///
1199/// [`HashTable`]: struct.HashTable.html
1200/// [`entry`]: struct.HashTable.html#method.entry
1201///
1202/// # Examples
1203///
1204/// ```
1205/// # #[cfg(feature = "nightly")]
1206/// # fn test() {
1207/// use hashbrown::hash_table::{Entry, OccupiedEntry};
1208/// use hashbrown::{HashTable, DefaultHashBuilder};
1209/// use std::hash::BuildHasher;
1210///
1211/// let mut table = HashTable::new();
1212/// let hasher = DefaultHashBuilder::default();
1213/// let hasher = |val: &_| hasher.hash_one(val);
1214/// for x in ["a", "b", "c"] {
1215///     table.insert_unique(hasher(&x), x, hasher);
1216/// }
1217/// assert_eq!(table.len(), 3);
1218///
1219/// // Existing value (insert)
1220/// let entry: Entry<_> = table.entry(hasher(&"a"), |&x| x == "a", hasher);
1221/// let _raw_o: OccupiedEntry<_, _> = entry.insert("a");
1222/// assert_eq!(table.len(), 3);
1223/// // Nonexistent value (insert)
1224/// table.entry(hasher(&"d"), |&x| x == "d", hasher).insert("d");
1225///
1226/// // Existing value (or_insert)
1227/// table
1228///     .entry(hasher(&"b"), |&x| x == "b", hasher)
1229///     .or_insert("b");
1230/// // Nonexistent value (or_insert)
1231/// table
1232///     .entry(hasher(&"e"), |&x| x == "e", hasher)
1233///     .or_insert("e");
1234///
1235/// println!("Our HashTable: {:?}", table);
1236///
1237/// let mut vec: Vec<_> = table.iter().copied().collect();
1238/// // The `Iter` iterator produces items in arbitrary order, so the
1239/// // items must be sorted to test them against a sorted array.
1240/// vec.sort_unstable();
1241/// assert_eq!(vec, ["a", "b", "c", "d", "e"]);
1242/// # }
1243/// # fn main() {
1244/// #     #[cfg(feature = "nightly")]
1245/// #     test()
1246/// # }
1247/// ```
1248pub enum Entry<'a, T, A = Global>
1249where
1250    A: Allocator,
1251{
1252    /// An occupied entry.
1253    ///
1254    /// # Examples
1255    ///
1256    /// ```
1257    /// # #[cfg(feature = "nightly")]
1258    /// # fn test() {
1259    /// use hashbrown::hash_table::{Entry, OccupiedEntry};
1260    /// use hashbrown::{HashTable, DefaultHashBuilder};
1261    /// use std::hash::BuildHasher;
1262    ///
1263    /// let mut table = HashTable::new();
1264    /// let hasher = DefaultHashBuilder::default();
1265    /// let hasher = |val: &_| hasher.hash_one(val);
1266    /// for x in ["a", "b"] {
1267    ///     table.insert_unique(hasher(&x), x, hasher);
1268    /// }
1269    ///
1270    /// match table.entry(hasher(&"a"), |&x| x == "a", hasher) {
1271    ///     Entry::Vacant(_) => unreachable!(),
1272    ///     Entry::Occupied(_) => {}
1273    /// }
1274    /// # }
1275    /// # fn main() {
1276    /// #     #[cfg(feature = "nightly")]
1277    /// #     test()
1278    /// # }
1279    /// ```
1280    Occupied(OccupiedEntry<'a, T, A>),
1281
1282    /// A vacant entry.
1283    ///
1284    /// # Examples
1285    ///
1286    /// ```
1287    /// # #[cfg(feature = "nightly")]
1288    /// # fn test() {
1289    /// use hashbrown::hash_table::{Entry, OccupiedEntry};
1290    /// use hashbrown::{HashTable, DefaultHashBuilder};
1291    /// use std::hash::BuildHasher;
1292    ///
1293    /// let mut table = HashTable::<&str>::new();
1294    /// let hasher = DefaultHashBuilder::default();
1295    /// let hasher = |val: &_| hasher.hash_one(val);
1296    ///
1297    /// match table.entry(hasher(&"a"), |&x| x == "a", hasher) {
1298    ///     Entry::Vacant(_) => {}
1299    ///     Entry::Occupied(_) => unreachable!(),
1300    /// }
1301    /// # }
1302    /// # fn main() {
1303    /// #     #[cfg(feature = "nightly")]
1304    /// #     test()
1305    /// # }
1306    /// ```
1307    Vacant(VacantEntry<'a, T, A>),
1308}
1309
1310impl<T: fmt::Debug, A: Allocator> fmt::Debug for Entry<'_, T, A> {
1311    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1312        match *self {
1313            Entry::Vacant(ref v) => f.debug_tuple("Entry").field(v).finish(),
1314            Entry::Occupied(ref o) => f.debug_tuple("Entry").field(o).finish(),
1315        }
1316    }
1317}
1318
1319impl<'a, T, A> Entry<'a, T, A>
1320where
1321    A: Allocator,
1322{
1323    /// Sets the value of the entry, replacing any existing value if there is
1324    /// one, and returns an [`OccupiedEntry`].
1325    ///
1326    /// # Examples
1327    ///
1328    /// ```
1329    /// # #[cfg(feature = "nightly")]
1330    /// # fn test() {
1331    /// use hashbrown::{HashTable, DefaultHashBuilder};
1332    /// use std::hash::BuildHasher;
1333    ///
1334    /// let mut table: HashTable<&str> = HashTable::new();
1335    /// let hasher = DefaultHashBuilder::default();
1336    /// let hasher = |val: &_| hasher.hash_one(val);
1337    ///
1338    /// let entry = table
1339    ///     .entry(hasher(&"horseyland"), |&x| x == "horseyland", hasher)
1340    ///     .insert("horseyland");
1341    ///
1342    /// assert_eq!(entry.get(), &"horseyland");
1343    /// # }
1344    /// # fn main() {
1345    /// #     #[cfg(feature = "nightly")]
1346    /// #     test()
1347    /// # }
1348    /// ```
1349    pub fn insert(self, value: T) -> OccupiedEntry<'a, T, A> {
1350        match self {
1351            Entry::Occupied(mut entry) => {
1352                *entry.get_mut() = value;
1353                entry
1354            }
1355            Entry::Vacant(entry) => entry.insert(value),
1356        }
1357    }
1358
1359    /// Ensures a value is in the entry by inserting if it was vacant.
1360    ///
1361    /// Returns an [`OccupiedEntry`] pointing to the now-occupied entry.
1362    ///
1363    /// # Examples
1364    ///
1365    /// ```
1366    /// # #[cfg(feature = "nightly")]
1367    /// # fn test() {
1368    /// use hashbrown::{HashTable, DefaultHashBuilder};
1369    /// use std::hash::BuildHasher;
1370    ///
1371    /// let mut table: HashTable<&str> = HashTable::new();
1372    /// let hasher = DefaultHashBuilder::default();
1373    /// let hasher = |val: &_| hasher.hash_one(val);
1374    ///
1375    /// // nonexistent key
1376    /// table
1377    ///     .entry(hasher(&"poneyland"), |&x| x == "poneyland", hasher)
1378    ///     .or_insert("poneyland");
1379    /// assert!(table
1380    ///     .find(hasher(&"poneyland"), |&x| x == "poneyland")
1381    ///     .is_some());
1382    ///
1383    /// // existing key
1384    /// table
1385    ///     .entry(hasher(&"poneyland"), |&x| x == "poneyland", hasher)
1386    ///     .or_insert("poneyland");
1387    /// assert!(table
1388    ///     .find(hasher(&"poneyland"), |&x| x == "poneyland")
1389    ///     .is_some());
1390    /// assert_eq!(table.len(), 1);
1391    /// # }
1392    /// # fn main() {
1393    /// #     #[cfg(feature = "nightly")]
1394    /// #     test()
1395    /// # }
1396    /// ```
1397    pub fn or_insert(self, default: T) -> OccupiedEntry<'a, T, A> {
1398        match self {
1399            Entry::Occupied(entry) => entry,
1400            Entry::Vacant(entry) => entry.insert(default),
1401        }
1402    }
1403
1404    /// Ensures a value is in the entry by inserting the result of the default function if empty..
1405    ///
1406    /// Returns an [`OccupiedEntry`] pointing to the now-occupied entry.
1407    ///
1408    /// # Examples
1409    ///
1410    /// ```
1411    /// # #[cfg(feature = "nightly")]
1412    /// # fn test() {
1413    /// use hashbrown::{HashTable, DefaultHashBuilder};
1414    /// use std::hash::BuildHasher;
1415    ///
1416    /// let mut table: HashTable<String> = HashTable::new();
1417    /// let hasher = DefaultHashBuilder::default();
1418    /// let hasher = |val: &_| hasher.hash_one(val);
1419    ///
1420    /// table
1421    ///     .entry(hasher("poneyland"), |x| x == "poneyland", |val| hasher(val))
1422    ///     .or_insert_with(|| "poneyland".to_string());
1423    ///
1424    /// assert!(table
1425    ///     .find(hasher(&"poneyland"), |x| x == "poneyland")
1426    ///     .is_some());
1427    /// # }
1428    /// # fn main() {
1429    /// #     #[cfg(feature = "nightly")]
1430    /// #     test()
1431    /// # }
1432    /// ```
1433    pub fn or_insert_with(self, default: impl FnOnce() -> T) -> OccupiedEntry<'a, T, A> {
1434        match self {
1435            Entry::Occupied(entry) => entry,
1436            Entry::Vacant(entry) => entry.insert(default()),
1437        }
1438    }
1439
1440    /// Provides in-place mutable access to an occupied entry before any
1441    /// potential inserts into the table.
1442    ///
1443    /// # Examples
1444    ///
1445    /// ```
1446    /// # #[cfg(feature = "nightly")]
1447    /// # fn test() {
1448    /// use hashbrown::{HashTable, DefaultHashBuilder};
1449    /// use std::hash::BuildHasher;
1450    ///
1451    /// let mut table: HashTable<(&str, u32)> = HashTable::new();
1452    /// let hasher = DefaultHashBuilder::default();
1453    /// let hasher = |val: &_| hasher.hash_one(val);
1454    ///
1455    /// table
1456    ///     .entry(
1457    ///         hasher(&"poneyland"),
1458    ///         |&(x, _)| x == "poneyland",
1459    ///         |(k, _)| hasher(&k),
1460    ///     )
1461    ///     .and_modify(|(_, v)| *v += 1)
1462    ///     .or_insert(("poneyland", 42));
1463    /// assert_eq!(
1464    ///     table.find(hasher(&"poneyland"), |&(k, _)| k == "poneyland"),
1465    ///     Some(&("poneyland", 42))
1466    /// );
1467    ///
1468    /// table
1469    ///     .entry(
1470    ///         hasher(&"poneyland"),
1471    ///         |&(x, _)| x == "poneyland",
1472    ///         |(k, _)| hasher(&k),
1473    ///     )
1474    ///     .and_modify(|(_, v)| *v += 1)
1475    ///     .or_insert(("poneyland", 42));
1476    /// assert_eq!(
1477    ///     table.find(hasher(&"poneyland"), |&(k, _)| k == "poneyland"),
1478    ///     Some(&("poneyland", 43))
1479    /// );
1480    /// # }
1481    /// # fn main() {
1482    /// #     #[cfg(feature = "nightly")]
1483    /// #     test()
1484    /// # }
1485    /// ```
1486    pub fn and_modify(self, f: impl FnOnce(&mut T)) -> Self {
1487        match self {
1488            Entry::Occupied(mut entry) => {
1489                f(entry.get_mut());
1490                Entry::Occupied(entry)
1491            }
1492            Entry::Vacant(entry) => Entry::Vacant(entry),
1493        }
1494    }
1495}
1496
1497/// A view into an occupied entry in a `HashTable`.
1498/// It is part of the [`Entry`] enum.
1499///
1500/// [`Entry`]: enum.Entry.html
1501///
1502/// # Examples
1503///
1504/// ```
1505/// # #[cfg(feature = "nightly")]
1506/// # fn test() {
1507/// use hashbrown::hash_table::{Entry, OccupiedEntry};
1508/// use hashbrown::{HashTable, DefaultHashBuilder};
1509/// use std::hash::BuildHasher;
1510///
1511/// let mut table = HashTable::new();
1512/// let hasher = DefaultHashBuilder::default();
1513/// let hasher = |val: &_| hasher.hash_one(val);
1514/// for x in ["a", "b", "c"] {
1515///     table.insert_unique(hasher(&x), x, hasher);
1516/// }
1517/// assert_eq!(table.len(), 3);
1518///
1519/// let _entry_o: OccupiedEntry<_, _> = table.find_entry(hasher(&"a"), |&x| x == "a").unwrap();
1520/// assert_eq!(table.len(), 3);
1521///
1522/// // Existing key
1523/// match table.entry(hasher(&"a"), |&x| x == "a", hasher) {
1524///     Entry::Vacant(_) => unreachable!(),
1525///     Entry::Occupied(view) => {
1526///         assert_eq!(view.get(), &"a");
1527///     }
1528/// }
1529///
1530/// assert_eq!(table.len(), 3);
1531///
1532/// // Existing key (take)
1533/// match table.entry(hasher(&"c"), |&x| x == "c", hasher) {
1534///     Entry::Vacant(_) => unreachable!(),
1535///     Entry::Occupied(view) => {
1536///         assert_eq!(view.remove().0, "c");
1537///     }
1538/// }
1539/// assert_eq!(table.find(hasher(&"c"), |&x| x == "c"), None);
1540/// assert_eq!(table.len(), 2);
1541/// # }
1542/// # fn main() {
1543/// #     #[cfg(feature = "nightly")]
1544/// #     test()
1545/// # }
1546/// ```
1547pub struct OccupiedEntry<'a, T, A = Global>
1548where
1549    A: Allocator,
1550{
1551    hash: u64,
1552    bucket: Bucket<T>,
1553    table: &'a mut HashTable<T, A>,
1554}
1555
1556unsafe impl<T, A> Send for OccupiedEntry<'_, T, A>
1557where
1558    T: Send,
1559    A: Send + Allocator,
1560{
1561}
1562unsafe impl<T, A> Sync for OccupiedEntry<'_, T, A>
1563where
1564    T: Sync,
1565    A: Sync + Allocator,
1566{
1567}
1568
1569impl<T: fmt::Debug, A: Allocator> fmt::Debug for OccupiedEntry<'_, T, A> {
1570    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1571        f.debug_struct("OccupiedEntry")
1572            .field("value", self.get())
1573            .finish()
1574    }
1575}
1576
1577impl<'a, T, A> OccupiedEntry<'a, T, A>
1578where
1579    A: Allocator,
1580{
1581    /// Takes the value out of the entry, and returns it along with a
1582    /// `VacantEntry` that can be used to insert another value with the same
1583    /// hash as the one that was just removed.
1584    ///
1585    /// # Examples
1586    ///
1587    /// ```
1588    /// # #[cfg(feature = "nightly")]
1589    /// # fn test() {
1590    /// use hashbrown::hash_table::Entry;
1591    /// use hashbrown::{HashTable, DefaultHashBuilder};
1592    /// use std::hash::BuildHasher;
1593    ///
1594    /// let mut table: HashTable<&str> = HashTable::new();
1595    /// let hasher = DefaultHashBuilder::default();
1596    /// let hasher = |val: &_| hasher.hash_one(val);
1597    /// // The table is empty
1598    /// assert!(table.is_empty() && table.capacity() == 0);
1599    ///
1600    /// table.insert_unique(hasher(&"poneyland"), "poneyland", hasher);
1601    /// let capacity_before_remove = table.capacity();
1602    ///
1603    /// if let Entry::Occupied(o) = table.entry(hasher(&"poneyland"), |&x| x == "poneyland", hasher) {
1604    ///     assert_eq!(o.remove().0, "poneyland");
1605    /// }
1606    ///
1607    /// assert!(table
1608    ///     .find(hasher(&"poneyland"), |&x| x == "poneyland")
1609    ///     .is_none());
1610    /// // Now table hold none elements but capacity is equal to the old one
1611    /// assert!(table.len() == 0 && table.capacity() == capacity_before_remove);
1612    /// # }
1613    /// # fn main() {
1614    /// #     #[cfg(feature = "nightly")]
1615    /// #     test()
1616    /// # }
1617    /// ```
1618    #[cfg_attr(feature = "inline-more", inline)]
1619    pub fn remove(self) -> (T, VacantEntry<'a, T, A>) {
1620        let (val, slot) = unsafe { self.table.raw.remove(self.bucket) };
1621        (
1622            val,
1623            VacantEntry {
1624                hash: self.hash,
1625                insert_slot: slot,
1626                table: self.table,
1627            },
1628        )
1629    }
1630
1631    /// Gets a reference to the value in the entry.
1632    ///
1633    /// # Examples
1634    ///
1635    /// ```
1636    /// # #[cfg(feature = "nightly")]
1637    /// # fn test() {
1638    /// use hashbrown::hash_table::Entry;
1639    /// use hashbrown::{HashTable, DefaultHashBuilder};
1640    /// use std::hash::BuildHasher;
1641    ///
1642    /// let mut table: HashTable<&str> = HashTable::new();
1643    /// let hasher = DefaultHashBuilder::default();
1644    /// let hasher = |val: &_| hasher.hash_one(val);
1645    /// table.insert_unique(hasher(&"poneyland"), "poneyland", hasher);
1646    ///
1647    /// match table.entry(hasher(&"poneyland"), |&x| x == "poneyland", hasher) {
1648    ///     Entry::Vacant(_) => panic!(),
1649    ///     Entry::Occupied(entry) => assert_eq!(entry.get(), &"poneyland"),
1650    /// }
1651    /// # }
1652    /// # fn main() {
1653    /// #     #[cfg(feature = "nightly")]
1654    /// #     test()
1655    /// # }
1656    /// ```
1657    #[inline]
1658    pub fn get(&self) -> &T {
1659        unsafe { self.bucket.as_ref() }
1660    }
1661
1662    /// Gets a mutable reference to the value in the entry.
1663    ///
1664    /// If you need a reference to the `OccupiedEntry` which may outlive the
1665    /// destruction of the `Entry` value, see [`into_mut`].
1666    ///
1667    /// [`into_mut`]: #method.into_mut
1668    ///
1669    /// # Examples
1670    ///
1671    /// ```
1672    /// # #[cfg(feature = "nightly")]
1673    /// # fn test() {
1674    /// use hashbrown::hash_table::Entry;
1675    /// use hashbrown::{HashTable, DefaultHashBuilder};
1676    /// use std::hash::BuildHasher;
1677    ///
1678    /// let mut table: HashTable<(&str, u32)> = HashTable::new();
1679    /// let hasher = DefaultHashBuilder::default();
1680    /// let hasher = |val: &_| hasher.hash_one(val);
1681    /// table.insert_unique(hasher(&"poneyland"), ("poneyland", 12), |(k, _)| hasher(&k));
1682    ///
1683    /// assert_eq!(
1684    ///     table.find(hasher(&"poneyland"), |&(x, _)| x == "poneyland",),
1685    ///     Some(&("poneyland", 12))
1686    /// );
1687    ///
1688    /// if let Entry::Occupied(mut o) = table.entry(
1689    ///     hasher(&"poneyland"),
1690    ///     |&(x, _)| x == "poneyland",
1691    ///     |(k, _)| hasher(&k),
1692    /// ) {
1693    ///     o.get_mut().1 += 10;
1694    ///     assert_eq!(o.get().1, 22);
1695    ///
1696    ///     // We can use the same Entry multiple times.
1697    ///     o.get_mut().1 += 2;
1698    /// }
1699    ///
1700    /// assert_eq!(
1701    ///     table.find(hasher(&"poneyland"), |&(x, _)| x == "poneyland",),
1702    ///     Some(&("poneyland", 24))
1703    /// );
1704    /// # }
1705    /// # fn main() {
1706    /// #     #[cfg(feature = "nightly")]
1707    /// #     test()
1708    /// # }
1709    /// ```
1710    #[inline]
1711    pub fn get_mut(&mut self) -> &mut T {
1712        unsafe { self.bucket.as_mut() }
1713    }
1714
1715    /// Converts the `OccupiedEntry` into a mutable reference to the value in the entry
1716    /// with a lifetime bound to the table itself.
1717    ///
1718    /// If you need multiple references to the `OccupiedEntry`, see [`get_mut`].
1719    ///
1720    /// [`get_mut`]: #method.get_mut
1721    ///
1722    /// # Examples
1723    ///
1724    /// ```
1725    /// # #[cfg(feature = "nightly")]
1726    /// # fn test() {
1727    /// use hashbrown::hash_table::Entry;
1728    /// use hashbrown::{HashTable, DefaultHashBuilder};
1729    /// use std::hash::BuildHasher;
1730    ///
1731    /// let mut table: HashTable<(&str, u32)> = HashTable::new();
1732    /// let hasher = DefaultHashBuilder::default();
1733    /// let hasher = |val: &_| hasher.hash_one(val);
1734    /// table.insert_unique(hasher(&"poneyland"), ("poneyland", 12), |(k, _)| hasher(&k));
1735    ///
1736    /// assert_eq!(
1737    ///     table.find(hasher(&"poneyland"), |&(x, _)| x == "poneyland",),
1738    ///     Some(&("poneyland", 12))
1739    /// );
1740    ///
1741    /// let value: &mut (&str, u32);
1742    /// match table.entry(
1743    ///     hasher(&"poneyland"),
1744    ///     |&(x, _)| x == "poneyland",
1745    ///     |(k, _)| hasher(&k),
1746    /// ) {
1747    ///     Entry::Occupied(entry) => value = entry.into_mut(),
1748    ///     Entry::Vacant(_) => panic!(),
1749    /// }
1750    /// value.1 += 10;
1751    ///
1752    /// assert_eq!(
1753    ///     table.find(hasher(&"poneyland"), |&(x, _)| x == "poneyland",),
1754    ///     Some(&("poneyland", 22))
1755    /// );
1756    /// # }
1757    /// # fn main() {
1758    /// #     #[cfg(feature = "nightly")]
1759    /// #     test()
1760    /// # }
1761    /// ```
1762    pub fn into_mut(self) -> &'a mut T {
1763        unsafe { self.bucket.as_mut() }
1764    }
1765
1766    /// Converts the `OccupiedEntry` into a mutable reference to the underlying
1767    /// table.
1768    pub fn into_table(self) -> &'a mut HashTable<T, A> {
1769        self.table
1770    }
1771}
1772
1773/// A view into a vacant entry in a `HashTable`.
1774/// It is part of the [`Entry`] enum.
1775///
1776/// [`Entry`]: enum.Entry.html
1777///
1778/// # Examples
1779///
1780/// ```
1781/// # #[cfg(feature = "nightly")]
1782/// # fn test() {
1783/// use hashbrown::hash_table::{Entry, VacantEntry};
1784/// use hashbrown::{HashTable, DefaultHashBuilder};
1785/// use std::hash::BuildHasher;
1786///
1787/// let mut table: HashTable<&str> = HashTable::new();
1788/// let hasher = DefaultHashBuilder::default();
1789/// let hasher = |val: &_| hasher.hash_one(val);
1790///
1791/// let entry_v: VacantEntry<_, _> = match table.entry(hasher(&"a"), |&x| x == "a", hasher) {
1792///     Entry::Vacant(view) => view,
1793///     Entry::Occupied(_) => unreachable!(),
1794/// };
1795/// entry_v.insert("a");
1796/// assert!(table.find(hasher(&"a"), |&x| x == "a").is_some() && table.len() == 1);
1797///
1798/// // Nonexistent key (insert)
1799/// match table.entry(hasher(&"b"), |&x| x == "b", hasher) {
1800///     Entry::Vacant(view) => {
1801///         view.insert("b");
1802///     }
1803///     Entry::Occupied(_) => unreachable!(),
1804/// }
1805/// assert!(table.find(hasher(&"b"), |&x| x == "b").is_some() && table.len() == 2);
1806/// # }
1807/// # fn main() {
1808/// #     #[cfg(feature = "nightly")]
1809/// #     test()
1810/// # }
1811/// ```
1812pub struct VacantEntry<'a, T, A = Global>
1813where
1814    A: Allocator,
1815{
1816    hash: u64,
1817    insert_slot: InsertSlot,
1818    table: &'a mut HashTable<T, A>,
1819}
1820
1821impl<T: fmt::Debug, A: Allocator> fmt::Debug for VacantEntry<'_, T, A> {
1822    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1823        f.write_str("VacantEntry")
1824    }
1825}
1826
1827impl<'a, T, A> VacantEntry<'a, T, A>
1828where
1829    A: Allocator,
1830{
1831    /// Inserts a new element into the table with the hash that was used to
1832    /// obtain the `VacantEntry`.
1833    ///
1834    /// An `OccupiedEntry` is returned for the newly inserted element.
1835    ///
1836    /// # Examples
1837    ///
1838    /// ```
1839    /// # #[cfg(feature = "nightly")]
1840    /// # fn test() {
1841    /// use hashbrown::hash_table::Entry;
1842    /// use hashbrown::{HashTable, DefaultHashBuilder};
1843    /// use std::hash::BuildHasher;
1844    ///
1845    /// let mut table: HashTable<&str> = HashTable::new();
1846    /// let hasher = DefaultHashBuilder::default();
1847    /// let hasher = |val: &_| hasher.hash_one(val);
1848    ///
1849    /// if let Entry::Vacant(o) = table.entry(hasher(&"poneyland"), |&x| x == "poneyland", hasher) {
1850    ///     o.insert("poneyland");
1851    /// }
1852    /// assert_eq!(
1853    ///     table.find(hasher(&"poneyland"), |&x| x == "poneyland"),
1854    ///     Some(&"poneyland")
1855    /// );
1856    /// # }
1857    /// # fn main() {
1858    /// #     #[cfg(feature = "nightly")]
1859    /// #     test()
1860    /// # }
1861    /// ```
1862    #[inline]
1863    pub fn insert(self, value: T) -> OccupiedEntry<'a, T, A> {
1864        let bucket = unsafe {
1865            self.table
1866                .raw
1867                .insert_in_slot(self.hash, self.insert_slot, value)
1868        };
1869        OccupiedEntry {
1870            hash: self.hash,
1871            bucket,
1872            table: self.table,
1873        }
1874    }
1875
1876    /// Converts the `VacantEntry` into a mutable reference to the underlying
1877    /// table.
1878    pub fn into_table(self) -> &'a mut HashTable<T, A> {
1879        self.table
1880    }
1881}
1882
1883/// Type representing the absence of an entry, as returned by [`HashTable::find_entry`].
1884///
1885/// This type only exists due to [limitations] in Rust's NLL borrow checker. In
1886/// the future, `find_entry` will return an `Option<OccupiedEntry>` and this
1887/// type will be removed.
1888///
1889/// [limitations]: https://smallcultfollowing.com/babysteps/blog/2018/06/15/mir-based-borrow-check-nll-status-update/#polonius
1890///
1891/// # Examples
1892///
1893/// ```
1894/// # #[cfg(feature = "nightly")]
1895/// # fn test() {
1896/// use hashbrown::hash_table::{AbsentEntry, Entry};
1897/// use hashbrown::{HashTable, DefaultHashBuilder};
1898/// use std::hash::BuildHasher;
1899///
1900/// let mut table: HashTable<&str> = HashTable::new();
1901/// let hasher = DefaultHashBuilder::default();
1902/// let hasher = |val: &_| hasher.hash_one(val);
1903///
1904/// let entry_v: AbsentEntry<_, _> = table.find_entry(hasher(&"a"), |&x| x == "a").unwrap_err();
1905/// entry_v
1906///     .into_table()
1907///     .insert_unique(hasher(&"a"), "a", hasher);
1908/// assert!(table.find(hasher(&"a"), |&x| x == "a").is_some() && table.len() == 1);
1909///
1910/// // Nonexistent key (insert)
1911/// match table.entry(hasher(&"b"), |&x| x == "b", hasher) {
1912///     Entry::Vacant(view) => {
1913///         view.insert("b");
1914///     }
1915///     Entry::Occupied(_) => unreachable!(),
1916/// }
1917/// assert!(table.find(hasher(&"b"), |&x| x == "b").is_some() && table.len() == 2);
1918/// # }
1919/// # fn main() {
1920/// #     #[cfg(feature = "nightly")]
1921/// #     test()
1922/// # }
1923/// ```
1924pub struct AbsentEntry<'a, T, A = Global>
1925where
1926    A: Allocator,
1927{
1928    table: &'a mut HashTable<T, A>,
1929}
1930
1931impl<T: fmt::Debug, A: Allocator> fmt::Debug for AbsentEntry<'_, T, A> {
1932    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1933        f.write_str("AbsentEntry")
1934    }
1935}
1936
1937impl<'a, T, A> AbsentEntry<'a, T, A>
1938where
1939    A: Allocator,
1940{
1941    /// Converts the `AbsentEntry` into a mutable reference to the underlying
1942    /// table.
1943    pub fn into_table(self) -> &'a mut HashTable<T, A> {
1944        self.table
1945    }
1946}
1947
1948/// An iterator over the entries of a `HashTable` in arbitrary order.
1949/// The iterator element type is `&'a T`.
1950///
1951/// This `struct` is created by the [`iter`] method on [`HashTable`]. See its
1952/// documentation for more.
1953///
1954/// [`iter`]: struct.HashTable.html#method.iter
1955/// [`HashTable`]: struct.HashTable.html
1956pub struct Iter<'a, T> {
1957    inner: RawIter<T>,
1958    marker: PhantomData<&'a T>,
1959}
1960
1961impl<T> Default for Iter<'_, T> {
1962    #[cfg_attr(feature = "inline-more", inline)]
1963    fn default() -> Self {
1964        Iter {
1965            inner: Default::default(),
1966            marker: PhantomData,
1967        }
1968    }
1969}
1970
1971impl<'a, T> Iterator for Iter<'a, T> {
1972    type Item = &'a T;
1973
1974    fn next(&mut self) -> Option<Self::Item> {
1975        // Avoid `Option::map` because it bloats LLVM IR.
1976        match self.inner.next() {
1977            Some(bucket) => Some(unsafe { bucket.as_ref() }),
1978            None => None,
1979        }
1980    }
1981
1982    fn size_hint(&self) -> (usize, Option<usize>) {
1983        self.inner.size_hint()
1984    }
1985
1986    fn fold<B, F>(self, init: B, mut f: F) -> B
1987    where
1988        Self: Sized,
1989        F: FnMut(B, Self::Item) -> B,
1990    {
1991        self.inner
1992            .fold(init, |acc, bucket| unsafe { f(acc, bucket.as_ref()) })
1993    }
1994}
1995
1996impl<T> ExactSizeIterator for Iter<'_, T> {
1997    fn len(&self) -> usize {
1998        self.inner.len()
1999    }
2000}
2001
2002impl<T> FusedIterator for Iter<'_, T> {}
2003
2004// FIXME(#26925) Remove in favor of `#[derive(Clone)]`
2005impl<'a, T> Clone for Iter<'a, T> {
2006    #[cfg_attr(feature = "inline-more", inline)]
2007    fn clone(&self) -> Iter<'a, T> {
2008        Iter {
2009            inner: self.inner.clone(),
2010            marker: PhantomData,
2011        }
2012    }
2013}
2014
2015impl<T: fmt::Debug> fmt::Debug for Iter<'_, T> {
2016    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2017        f.debug_list().entries(self.clone()).finish()
2018    }
2019}
2020
2021/// A mutable iterator over the entries of a `HashTable` in arbitrary order.
2022/// The iterator element type is `&'a mut T`.
2023///
2024/// This `struct` is created by the [`iter_mut`] method on [`HashTable`]. See its
2025/// documentation for more.
2026///
2027/// [`iter_mut`]: struct.HashTable.html#method.iter_mut
2028/// [`HashTable`]: struct.HashTable.html
2029pub struct IterMut<'a, T> {
2030    inner: RawIter<T>,
2031    marker: PhantomData<&'a mut T>,
2032}
2033
2034impl<T> Default for IterMut<'_, T> {
2035    #[cfg_attr(feature = "inline-more", inline)]
2036    fn default() -> Self {
2037        IterMut {
2038            inner: Default::default(),
2039            marker: PhantomData,
2040        }
2041    }
2042}
2043impl<'a, T> Iterator for IterMut<'a, T> {
2044    type Item = &'a mut T;
2045
2046    fn next(&mut self) -> Option<Self::Item> {
2047        // Avoid `Option::map` because it bloats LLVM IR.
2048        match self.inner.next() {
2049            Some(bucket) => Some(unsafe { bucket.as_mut() }),
2050            None => None,
2051        }
2052    }
2053
2054    fn size_hint(&self) -> (usize, Option<usize>) {
2055        self.inner.size_hint()
2056    }
2057
2058    fn fold<B, F>(self, init: B, mut f: F) -> B
2059    where
2060        Self: Sized,
2061        F: FnMut(B, Self::Item) -> B,
2062    {
2063        self.inner
2064            .fold(init, |acc, bucket| unsafe { f(acc, bucket.as_mut()) })
2065    }
2066}
2067
2068impl<T> ExactSizeIterator for IterMut<'_, T> {
2069    fn len(&self) -> usize {
2070        self.inner.len()
2071    }
2072}
2073
2074impl<T> FusedIterator for IterMut<'_, T> {}
2075
2076impl<T> fmt::Debug for IterMut<'_, T>
2077where
2078    T: fmt::Debug,
2079{
2080    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2081        f.debug_list()
2082            .entries(Iter {
2083                inner: self.inner.clone(),
2084                marker: PhantomData,
2085            })
2086            .finish()
2087    }
2088}
2089
2090/// An iterator over the entries of a `HashTable` that could match a given hash.
2091/// The iterator element type is `&'a T`.
2092///
2093/// This `struct` is created by the [`iter_hash`] method on [`HashTable`]. See its
2094/// documentation for more.
2095///
2096/// [`iter_hash`]: struct.HashTable.html#method.iter_hash
2097/// [`HashTable`]: struct.HashTable.html
2098pub struct IterHash<'a, T> {
2099    inner: RawIterHash<T>,
2100    marker: PhantomData<&'a T>,
2101}
2102
2103impl<T> Default for IterHash<'_, T> {
2104    #[cfg_attr(feature = "inline-more", inline)]
2105    fn default() -> Self {
2106        IterHash {
2107            inner: Default::default(),
2108            marker: PhantomData,
2109        }
2110    }
2111}
2112
2113impl<'a, T> Iterator for IterHash<'a, T> {
2114    type Item = &'a T;
2115
2116    fn next(&mut self) -> Option<Self::Item> {
2117        // Avoid `Option::map` because it bloats LLVM IR.
2118        match self.inner.next() {
2119            Some(bucket) => Some(unsafe { bucket.as_ref() }),
2120            None => None,
2121        }
2122    }
2123
2124    fn fold<B, F>(self, init: B, mut f: F) -> B
2125    where
2126        Self: Sized,
2127        F: FnMut(B, Self::Item) -> B,
2128    {
2129        self.inner
2130            .fold(init, |acc, bucket| unsafe { f(acc, bucket.as_ref()) })
2131    }
2132}
2133
2134impl<T> FusedIterator for IterHash<'_, T> {}
2135
2136// FIXME(#26925) Remove in favor of `#[derive(Clone)]`
2137impl<'a, T> Clone for IterHash<'a, T> {
2138    #[cfg_attr(feature = "inline-more", inline)]
2139    fn clone(&self) -> IterHash<'a, T> {
2140        IterHash {
2141            inner: self.inner.clone(),
2142            marker: PhantomData,
2143        }
2144    }
2145}
2146
2147impl<T> fmt::Debug for IterHash<'_, T>
2148where
2149    T: fmt::Debug,
2150{
2151    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2152        f.debug_list().entries(self.clone()).finish()
2153    }
2154}
2155
2156/// A mutable iterator over the entries of a `HashTable` that could match a given hash.
2157/// The iterator element type is `&'a mut T`.
2158///
2159/// This `struct` is created by the [`iter_hash_mut`] method on [`HashTable`]. See its
2160/// documentation for more.
2161///
2162/// [`iter_hash_mut`]: struct.HashTable.html#method.iter_hash_mut
2163/// [`HashTable`]: struct.HashTable.html
2164pub struct IterHashMut<'a, T> {
2165    inner: RawIterHash<T>,
2166    marker: PhantomData<&'a mut T>,
2167}
2168
2169impl<T> Default for IterHashMut<'_, T> {
2170    #[cfg_attr(feature = "inline-more", inline)]
2171    fn default() -> Self {
2172        IterHashMut {
2173            inner: Default::default(),
2174            marker: PhantomData,
2175        }
2176    }
2177}
2178
2179impl<'a, T> Iterator for IterHashMut<'a, T> {
2180    type Item = &'a mut T;
2181
2182    fn next(&mut self) -> Option<Self::Item> {
2183        // Avoid `Option::map` because it bloats LLVM IR.
2184        match self.inner.next() {
2185            Some(bucket) => Some(unsafe { bucket.as_mut() }),
2186            None => None,
2187        }
2188    }
2189
2190    fn fold<B, F>(self, init: B, mut f: F) -> B
2191    where
2192        Self: Sized,
2193        F: FnMut(B, Self::Item) -> B,
2194    {
2195        self.inner
2196            .fold(init, |acc, bucket| unsafe { f(acc, bucket.as_mut()) })
2197    }
2198}
2199
2200impl<T> FusedIterator for IterHashMut<'_, T> {}
2201
2202impl<T> fmt::Debug for IterHashMut<'_, T>
2203where
2204    T: fmt::Debug,
2205{
2206    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2207        f.debug_list()
2208            .entries(IterHash {
2209                inner: self.inner.clone(),
2210                marker: PhantomData,
2211            })
2212            .finish()
2213    }
2214}
2215
2216/// An owning iterator over the entries of a `HashTable` in arbitrary order.
2217/// The iterator element type is `T`.
2218///
2219/// This `struct` is created by the [`into_iter`] method on [`HashTable`]
2220/// (provided by the [`IntoIterator`] trait). See its documentation for more.
2221/// The table cannot be used after calling that method.
2222///
2223/// [`into_iter`]: struct.HashTable.html#method.into_iter
2224/// [`HashTable`]: struct.HashTable.html
2225/// [`IntoIterator`]: https://doc.rust-lang.org/core/iter/trait.IntoIterator.html
2226pub struct IntoIter<T, A = Global>
2227where
2228    A: Allocator,
2229{
2230    inner: RawIntoIter<T, A>,
2231}
2232
2233impl<T, A: Allocator> Default for IntoIter<T, A> {
2234    #[cfg_attr(feature = "inline-more", inline)]
2235    fn default() -> Self {
2236        IntoIter {
2237            inner: Default::default(),
2238        }
2239    }
2240}
2241
2242impl<T, A> Iterator for IntoIter<T, A>
2243where
2244    A: Allocator,
2245{
2246    type Item = T;
2247
2248    fn next(&mut self) -> Option<Self::Item> {
2249        self.inner.next()
2250    }
2251
2252    fn size_hint(&self) -> (usize, Option<usize>) {
2253        self.inner.size_hint()
2254    }
2255
2256    fn fold<B, F>(self, init: B, f: F) -> B
2257    where
2258        Self: Sized,
2259        F: FnMut(B, Self::Item) -> B,
2260    {
2261        self.inner.fold(init, f)
2262    }
2263}
2264
2265impl<T, A> ExactSizeIterator for IntoIter<T, A>
2266where
2267    A: Allocator,
2268{
2269    fn len(&self) -> usize {
2270        self.inner.len()
2271    }
2272}
2273
2274impl<T, A> FusedIterator for IntoIter<T, A> where A: Allocator {}
2275
2276impl<T, A> fmt::Debug for IntoIter<T, A>
2277where
2278    T: fmt::Debug,
2279    A: Allocator,
2280{
2281    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2282        f.debug_list()
2283            .entries(Iter {
2284                inner: self.inner.iter(),
2285                marker: PhantomData,
2286            })
2287            .finish()
2288    }
2289}
2290
2291/// A draining iterator over the items of a `HashTable`.
2292///
2293/// This `struct` is created by the [`drain`] method on [`HashTable`].
2294/// See its documentation for more.
2295///
2296/// [`HashTable`]: struct.HashTable.html
2297/// [`drain`]: struct.HashTable.html#method.drain
2298pub struct Drain<'a, T, A: Allocator = Global> {
2299    inner: RawDrain<'a, T, A>,
2300}
2301
2302impl<T, A: Allocator> Iterator for Drain<'_, T, A> {
2303    type Item = T;
2304
2305    fn next(&mut self) -> Option<T> {
2306        self.inner.next()
2307    }
2308
2309    fn size_hint(&self) -> (usize, Option<usize>) {
2310        self.inner.size_hint()
2311    }
2312
2313    fn fold<B, F>(self, init: B, f: F) -> B
2314    where
2315        Self: Sized,
2316        F: FnMut(B, Self::Item) -> B,
2317    {
2318        self.inner.fold(init, f)
2319    }
2320}
2321
2322impl<T, A: Allocator> ExactSizeIterator for Drain<'_, T, A> {
2323    fn len(&self) -> usize {
2324        self.inner.len()
2325    }
2326}
2327
2328impl<T, A: Allocator> FusedIterator for Drain<'_, T, A> {}
2329
2330impl<T: fmt::Debug, A: Allocator> fmt::Debug for Drain<'_, T, A> {
2331    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2332        f.debug_list()
2333            .entries(Iter {
2334                inner: self.inner.iter(),
2335                marker: PhantomData,
2336            })
2337            .finish()
2338    }
2339}
2340
2341/// A draining iterator over entries of a `HashTable` which don't satisfy the predicate `f`.
2342///
2343/// This `struct` is created by [`HashTable::extract_if`]. See its
2344/// documentation for more.
2345#[must_use = "Iterators are lazy unless consumed"]
2346pub struct ExtractIf<'a, T, F, A: Allocator = Global>
2347where
2348    F: FnMut(&mut T) -> bool,
2349{
2350    f: F,
2351    inner: RawExtractIf<'a, T, A>,
2352}
2353
2354impl<T, F, A: Allocator> Iterator for ExtractIf<'_, T, F, A>
2355where
2356    F: FnMut(&mut T) -> bool,
2357{
2358    type Item = T;
2359
2360    #[inline]
2361    fn next(&mut self) -> Option<Self::Item> {
2362        self.inner.next(|val| (self.f)(val))
2363    }
2364
2365    #[inline]
2366    fn size_hint(&self) -> (usize, Option<usize>) {
2367        (0, self.inner.iter.size_hint().1)
2368    }
2369}
2370
2371impl<T, F, A: Allocator> FusedIterator for ExtractIf<'_, T, F, A> where F: FnMut(&mut T) -> bool {}
2372
2373#[cfg(test)]
2374mod tests {
2375    use super::HashTable;
2376
2377    #[test]
2378    fn test_allocation_info() {
2379        assert_eq!(HashTable::<()>::new().allocation_size(), 0);
2380        assert_eq!(HashTable::<u32>::new().allocation_size(), 0);
2381        assert!(HashTable::<u32>::with_capacity(1).allocation_size() > core::mem::size_of::<u32>());
2382    }
2383}