Coverage Report

Created: 2026-06-01 06:40

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