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