hashbrown/raw/
mod.rs

1use crate::alloc::alloc::{handle_alloc_error, Layout};
2use crate::control::{BitMaskIter, Group, Tag, TagSliceExt};
3use crate::scopeguard::{guard, ScopeGuard};
4use crate::util::{invalid_mut, likely, unlikely};
5use crate::TryReserveError;
6use core::array;
7use core::iter::FusedIterator;
8use core::marker::PhantomData;
9use core::mem;
10use core::ptr::NonNull;
11use core::slice;
12use core::{hint, ptr};
13
14mod alloc;
15#[cfg(test)]
16pub(crate) use self::alloc::AllocError;
17pub(crate) use self::alloc::{do_alloc, Allocator, Global};
18
19#[inline]
20unsafe fn offset_from<T>(to: *const T, from: *const T) -> usize {
21    to.offset_from(from) as usize
22}
23
24/// Whether memory allocation errors should return an error or abort.
25#[derive(Copy, Clone)]
26enum Fallibility {
27    Fallible,
28    Infallible,
29}
30
31impl Fallibility {
32    /// Error to return on capacity overflow.
33    #[cfg_attr(feature = "inline-more", inline)]
34    fn capacity_overflow(self) -> TryReserveError {
35        match self {
36            Fallibility::Fallible => TryReserveError::CapacityOverflow,
37            Fallibility::Infallible => panic!("Hash table capacity overflow"),
38        }
39    }
40
41    /// Error to return on allocation error.
42    #[cfg_attr(feature = "inline-more", inline)]
43    fn alloc_err(self, layout: Layout) -> TryReserveError {
44        match self {
45            Fallibility::Fallible => TryReserveError::AllocError { layout },
46            Fallibility::Infallible => handle_alloc_error(layout),
47        }
48    }
49}
50
51trait SizedTypeProperties: Sized {
52    const IS_ZERO_SIZED: bool = mem::size_of::<Self>() == 0;
53    const NEEDS_DROP: bool = mem::needs_drop::<Self>();
54}
55
56impl<T> SizedTypeProperties for T {}
57
58/// Primary hash function, used to select the initial bucket to probe from.
59#[inline]
60#[allow(clippy::cast_possible_truncation)]
61fn h1(hash: u64) -> usize {
62    // On 32-bit platforms we simply ignore the higher hash bits.
63    hash as usize
64}
65
66/// Probe sequence based on triangular numbers, which is guaranteed (since our
67/// table size is a power of two) to visit every group of elements exactly once.
68///
69/// A triangular probe has us jump by 1 more group every time. So first we
70/// jump by 1 group (meaning we just continue our linear scan), then 2 groups
71/// (skipping over 1 group), then 3 groups (skipping over 2 groups), and so on.
72///
73/// Proof that the probe will visit every group in the table:
74/// <https://fgiesen.wordpress.com/2015/02/22/triangular-numbers-mod-2n/>
75#[derive(Clone)]
76struct ProbeSeq {
77    pos: usize,
78    stride: usize,
79}
80
81impl ProbeSeq {
82    #[inline]
83    fn move_next(&mut self, bucket_mask: usize) {
84        // We should have found an empty bucket by now and ended the probe.
85        debug_assert!(
86            self.stride <= bucket_mask,
87            "Went past end of probe sequence"
88        );
89
90        self.stride += Group::WIDTH;
91        self.pos += self.stride;
92        self.pos &= bucket_mask;
93    }
94}
95
96/// Returns the number of buckets needed to hold the given number of items,
97/// taking the maximum load factor into account.
98///
99/// Returns `None` if an overflow occurs.
100///
101/// This ensures that `buckets * table_layout.size >= table_layout.ctrl_align`.
102// Workaround for emscripten bug emscripten-core/emscripten-fastcomp#258
103#[cfg_attr(target_os = "emscripten", inline(never))]
104#[cfg_attr(not(target_os = "emscripten"), inline)]
105fn capacity_to_buckets(cap: usize, table_layout: TableLayout) -> Option<usize> {
106    debug_assert_ne!(cap, 0);
107
108    // For small tables we require at least 1 empty bucket so that lookups are
109    // guaranteed to terminate if an element doesn't exist in the table.
110    if cap < 15 {
111        // Consider a small TableLayout like { size: 1, ctrl_align: 16 } on a
112        // platform with Group::WIDTH of 16 (like x86_64 with SSE2). For small
113        // bucket sizes, this ends up wasting quite a few bytes just to pad to
114        // the relatively larger ctrl_align:
115        //
116        // | capacity | buckets | bytes allocated | bytes per item |
117        // | -------- | ------- | --------------- | -------------- |
118        // |        3 |       4 |              36 | (Yikes!)  12.0 |
119        // |        7 |       8 |              40 | (Poor)     5.7 |
120        // |       14 |      16 |              48 |            3.4 |
121        // |       28 |      32 |              80 |            3.3 |
122        //
123        // In general, buckets * table_layout.size >= table_layout.ctrl_align
124        // must be true to avoid these edges. This is implemented by adjusting
125        // the minimum capacity upwards for small items. This code only needs
126        // to handle ctrl_align which are less than or equal to Group::WIDTH,
127        // because valid layout sizes are always a multiple of the alignment,
128        // so anything with alignment over the Group::WIDTH won't hit this edge
129        // case.
130
131        // This is brittle, e.g. if we ever add 32 byte groups, it will select
132        // 3 regardless of the table_layout.size.
133        let min_cap = match (Group::WIDTH, table_layout.size) {
134            (16, 0..=1) => 14,
135            (16, 2..=3) => 7,
136            (8, 0..=1) => 7,
137            _ => 3,
138        };
139        let cap = min_cap.max(cap);
140        // We don't bother with a table size of 2 buckets since that can only
141        // hold a single element. Instead, we skip directly to a 4 bucket table
142        // which can hold 3 elements.
143        let buckets = if cap < 4 {
144            4
145        } else if cap < 8 {
146            8
147        } else {
148            16
149        };
150        ensure_bucket_bytes_at_least_ctrl_align(table_layout, buckets);
151        return Some(buckets);
152    }
153
154    // Otherwise require 1/8 buckets to be empty (87.5% load)
155    //
156    // Be careful when modifying this, calculate_layout relies on the
157    // overflow check here.
158    let adjusted_cap = cap.checked_mul(8)? / 7;
159
160    // Any overflows will have been caught by the checked_mul. Also, any
161    // rounding errors from the division above will be cleaned up by
162    // next_power_of_two (which can't overflow because of the previous division).
163    let buckets = adjusted_cap.next_power_of_two();
164    ensure_bucket_bytes_at_least_ctrl_align(table_layout, buckets);
165    Some(buckets)
166}
167
168// `maximum_buckets_in` relies on the property that for non-ZST `T`, any
169// chosen `buckets` will satisfy `buckets * table_layout.size >=
170// table_layout.ctrl_align`, so `calculate_layout_for` does not need to add
171// extra padding beyond `table_layout.size * buckets`. If small-table bucket
172// selection or growth policy changes, revisit `maximum_buckets_in`.
173#[inline]
174fn ensure_bucket_bytes_at_least_ctrl_align(table_layout: TableLayout, buckets: usize) {
175    if table_layout.size != 0 {
176        let prod = table_layout.size.saturating_mul(buckets);
177        debug_assert!(prod >= table_layout.ctrl_align);
178    }
179}
180
181/// Returns the maximum effective capacity for the given bucket mask, taking
182/// the maximum load factor into account.
183#[inline]
184fn bucket_mask_to_capacity(bucket_mask: usize) -> usize {
185    if bucket_mask < 8 {
186        // For tables with 1/2/4/8 buckets, we always reserve one empty slot.
187        // Keep in mind that the bucket mask is one less than the bucket count.
188        bucket_mask
189    } else {
190        // For larger tables we reserve 12.5% of the slots as empty.
191        ((bucket_mask + 1) / 8) * 7
192    }
193}
194
195/// Helper which allows the max calculation for `ctrl_align` to be statically computed for each `T`
196/// while keeping the rest of `calculate_layout_for` independent of `T`
197#[derive(Copy, Clone)]
198struct TableLayout {
199    size: usize,
200    ctrl_align: usize,
201}
202
203impl TableLayout {
204    #[inline]
205    const fn new<T>() -> Self {
206        let layout = Layout::new::<T>();
207        Self {
208            size: layout.size(),
209            ctrl_align: if layout.align() > Group::WIDTH {
210                layout.align()
211            } else {
212                Group::WIDTH
213            },
214        }
215    }
216
217    #[inline]
218    fn calculate_layout_for(self, buckets: usize) -> Option<(Layout, usize)> {
219        debug_assert!(buckets.is_power_of_two());
220
221        let TableLayout { size, ctrl_align } = self;
222        // Manual layout calculation since Layout methods are not yet stable.
223        let ctrl_offset =
224            size.checked_mul(buckets)?.checked_add(ctrl_align - 1)? & !(ctrl_align - 1);
225        let len = ctrl_offset.checked_add(buckets + Group::WIDTH)?;
226
227        // We need an additional check to ensure that the allocation doesn't
228        // exceed `isize::MAX` (https://github.com/rust-lang/rust/pull/95295).
229        if len > isize::MAX as usize - (ctrl_align - 1) {
230            return None;
231        }
232
233        Some((
234            unsafe { Layout::from_size_align_unchecked(len, ctrl_align) },
235            ctrl_offset,
236        ))
237    }
238}
239
240/// A reference to a hash table bucket containing a `T`.
241///
242/// This is usually just a pointer to the element itself. However if the element
243/// is a ZST, then we instead track the index of the element in the table so
244/// that `erase` works properly.
245pub struct Bucket<T> {
246    // Actually it is pointer to next element than element itself
247    // this is needed to maintain pointer arithmetic invariants
248    // keeping direct pointer to element introduces difficulty.
249    // Using `NonNull` for variance and niche layout
250    ptr: NonNull<T>,
251}
252
253// This Send impl is needed for rayon support. This is safe since Bucket is
254// never exposed in a public API.
255unsafe impl<T> Send for Bucket<T> {}
256
257impl<T> Clone for Bucket<T> {
258    #[inline]
259    fn clone(&self) -> Self {
260        Self { ptr: self.ptr }
261    }
262}
263
264impl<T> Bucket<T> {
265    /// Creates a [`Bucket`] that contain pointer to the data.
266    /// The pointer calculation is performed by calculating the
267    /// offset from given `base` pointer (convenience for
268    /// `base.as_ptr().sub(index)`).
269    ///
270    /// `index` is in units of `T`; e.g., an `index` of 3 represents a pointer
271    /// offset of `3 * size_of::<T>()` bytes.
272    ///
273    /// If the `T` is a ZST, then we instead track the index of the element
274    /// in the table so that `erase` works properly (return
275    /// `NonNull::new_unchecked((index + 1) as *mut T)`)
276    ///
277    /// # Safety
278    ///
279    /// If `mem::size_of::<T>() != 0`, then the safety rules are directly derived
280    /// from the safety rules for [`<*mut T>::sub`] method of `*mut T` and the safety
281    /// rules of [`NonNull::new_unchecked`] function.
282    ///
283    /// Thus, in order to uphold the safety contracts for the [`<*mut T>::sub`] method
284    /// and [`NonNull::new_unchecked`] function, as well as for the correct
285    /// logic of the work of this crate, the following rules are necessary and
286    /// sufficient:
287    ///
288    /// * the `base` pointer must not be `dangling` and must points to the
289    ///   end of the first `value element` from the `data part` of the table, i.e.
290    ///   must be the pointer that returned by [`RawTable::data_end`] or by
291    ///   [`RawTableInner::data_end<T>`];
292    ///
293    /// * `index` must not be greater than `RawTableInner.bucket_mask`, i.e.
294    ///   `index <= RawTableInner.bucket_mask` or, in other words, `(index + 1)`
295    ///   must be no greater than the number returned by the function
296    ///   [`RawTable::buckets`] or [`RawTableInner::buckets`].
297    ///
298    /// If `mem::size_of::<T>() == 0`, then the only requirement is that the
299    /// `index` must not be greater than `RawTableInner.bucket_mask`, i.e.
300    /// `index <= RawTableInner.bucket_mask` or, in other words, `(index + 1)`
301    /// must be no greater than the number returned by the function
302    /// [`RawTable::buckets`] or [`RawTableInner::buckets`].
303    ///
304    /// [`Bucket`]: crate::raw::Bucket
305    /// [`<*mut T>::sub`]: https://doc.rust-lang.org/core/primitive.pointer.html#method.sub-1
306    /// [`NonNull::new_unchecked`]: https://doc.rust-lang.org/stable/std/ptr/struct.NonNull.html#method.new_unchecked
307    /// [`RawTable::data_end`]: crate::raw::RawTable::data_end
308    /// [`RawTableInner::data_end<T>`]: RawTableInner::data_end<T>
309    /// [`RawTable::buckets`]: crate::raw::RawTable::buckets
310    /// [`RawTableInner::buckets`]: RawTableInner::buckets
311    #[inline]
312    unsafe fn from_base_index(base: NonNull<T>, index: usize) -> Self {
313        // If mem::size_of::<T>() != 0 then return a pointer to an `element` in
314        // the data part of the table (we start counting from "0", so that
315        // in the expression T[last], the "last" index actually one less than the
316        // "buckets" number in the table, i.e. "last = RawTableInner.bucket_mask"):
317        //
318        //                   `from_base_index(base, 1).as_ptr()` returns a pointer that
319        //                   points here in the data part of the table
320        //                   (to the start of T1)
321        //                        |
322        //                        |        `base: NonNull<T>` must point here
323        //                        |         (to the end of T0 or to the start of C0)
324        //                        v         v
325        // [Padding], Tlast, ..., |T1|, T0, |C0, C1, ..., Clast
326        //                           ^
327        //                           `from_base_index(base, 1)` returns a pointer
328        //                           that points here in the data part of the table
329        //                           (to the end of T1)
330        //
331        // where: T0...Tlast - our stored data; C0...Clast - control bytes
332        // or metadata for data.
333        let ptr = if T::IS_ZERO_SIZED {
334            // won't overflow because index must be less than length (bucket_mask)
335            // and bucket_mask is guaranteed to be less than `isize::MAX`
336            // (see TableLayout::calculate_layout_for method)
337            invalid_mut(index + 1)
338        } else {
339            base.as_ptr().sub(index)
340        };
341        Self {
342            ptr: NonNull::new_unchecked(ptr),
343        }
344    }
345
346    /// Calculates the index of a [`Bucket`] as distance between two pointers
347    /// (convenience for `base.as_ptr().offset_from(self.ptr.as_ptr()) as usize`).
348    /// The returned value is in units of T: the distance in bytes divided by
349    /// [`core::mem::size_of::<T>()`].
350    ///
351    /// If the `T` is a ZST, then we return the index of the element in
352    /// the table so that `erase` works properly (return `self.ptr.as_ptr() as usize - 1`).
353    ///
354    /// This function is the inverse of [`from_base_index`].
355    ///
356    /// # Safety
357    ///
358    /// If `mem::size_of::<T>() != 0`, then the safety rules are directly derived
359    /// from the safety rules for [`<*const T>::offset_from`] method of `*const T`.
360    ///
361    /// Thus, in order to uphold the safety contracts for [`<*const T>::offset_from`]
362    /// method, as well as for the correct logic of the work of this crate, the
363    /// following rules are necessary and sufficient:
364    ///
365    /// * `base` contained pointer must not be `dangling` and must point to the
366    ///   end of the first `element` from the `data part` of the table, i.e.
367    ///   must be a pointer that returns by [`RawTable::data_end`] or by
368    ///   [`RawTableInner::data_end<T>`];
369    ///
370    /// * `self` also must not contain dangling pointer;
371    ///
372    /// * both `self` and `base` must be created from the same [`RawTable`]
373    ///   (or [`RawTableInner`]).
374    ///
375    /// If `mem::size_of::<T>() == 0`, this function is always safe.
376    ///
377    /// [`Bucket`]: crate::raw::Bucket
378    /// [`from_base_index`]: crate::raw::Bucket::from_base_index
379    /// [`RawTable::data_end`]: crate::raw::RawTable::data_end
380    /// [`RawTableInner::data_end<T>`]: RawTableInner::data_end<T>
381    /// [`RawTable`]: crate::raw::RawTable
382    /// [`RawTableInner`]: RawTableInner
383    /// [`<*const T>::offset_from`]: https://doc.rust-lang.org/nightly/core/primitive.pointer.html#method.offset_from
384    #[inline]
385    unsafe fn to_base_index(&self, base: NonNull<T>) -> usize {
386        // If mem::size_of::<T>() != 0 then return an index under which we used to store the
387        // `element` in the data part of the table (we start counting from "0", so
388        // that in the expression T[last], the "last" index actually is one less than the
389        // "buckets" number in the table, i.e. "last = RawTableInner.bucket_mask").
390        // For example for 5th element in table calculation is performed like this:
391        //
392        //                        mem::size_of::<T>()
393        //                          |
394        //                          |         `self = from_base_index(base, 5)` that returns pointer
395        //                          |         that points here in the data part of the table
396        //                          |         (to the end of T5)
397        //                          |           |                    `base: NonNull<T>` must point here
398        //                          v           |                    (to the end of T0 or to the start of C0)
399        //                        /???\         v                      v
400        // [Padding], Tlast, ..., |T10|, ..., T5|, T4, T3, T2, T1, T0, |C0, C1, C2, C3, C4, C5, ..., C10, ..., Clast
401        //                                      \__________  __________/
402        //                                                 \/
403        //                                     `bucket.to_base_index(base)` = 5
404        //                                     (base.as_ptr() as usize - self.ptr.as_ptr() as usize) / mem::size_of::<T>()
405        //
406        // where: T0...Tlast - our stored data; C0...Clast - control bytes or metadata for data.
407        if T::IS_ZERO_SIZED {
408            // this can not be UB
409            self.ptr.as_ptr() as usize - 1
410        } else {
411            offset_from(base.as_ptr(), self.ptr.as_ptr())
412        }
413    }
414
415    /// Acquires the underlying raw pointer `*mut T` to `data`.
416    ///
417    /// # Note
418    ///
419    /// If `T` is not [`Copy`], do not use `*mut T` methods that can cause calling the
420    /// destructor of `T` (for example the [`<*mut T>::drop_in_place`] method), because
421    /// for properly dropping the data we also need to clear `data` control bytes. If we
422    /// drop data, but do not clear `data control byte` it leads to double drop when
423    /// [`RawTable`] goes out of scope.
424    ///
425    /// If you modify an already initialized `value`, so [`Hash`] and [`Eq`] on the new
426    /// `T` value and its borrowed form *must* match those for the old `T` value, as the map
427    /// will not re-evaluate where the new value should go, meaning the value may become
428    /// "lost" if their location does not reflect their state.
429    ///
430    /// [`RawTable`]: crate::raw::RawTable
431    /// [`<*mut T>::drop_in_place`]: https://doc.rust-lang.org/core/primitive.pointer.html#method.drop_in_place
432    /// [`Hash`]: https://doc.rust-lang.org/core/hash/trait.Hash.html
433    /// [`Eq`]: https://doc.rust-lang.org/core/cmp/trait.Eq.html
434    #[inline]
435    pub fn as_ptr(&self) -> *mut T {
436        if T::IS_ZERO_SIZED {
437            // Just return an arbitrary ZST pointer which is properly aligned
438            // invalid pointer is good enough for ZST
439            invalid_mut(mem::align_of::<T>())
440        } else {
441            unsafe { self.ptr.as_ptr().sub(1) }
442        }
443    }
444
445    /// Acquires the underlying non-null pointer `*mut T` to `data`.
446    #[inline]
447    fn as_non_null(&self) -> NonNull<T> {
448        // SAFETY: `self.ptr` is already a `NonNull`
449        unsafe { NonNull::new_unchecked(self.as_ptr()) }
450    }
451
452    /// Create a new [`Bucket`] that is offset from the `self` by the given
453    /// `offset`. The pointer calculation is performed by calculating the
454    /// offset from `self` pointer (convenience for `self.ptr.as_ptr().sub(offset)`).
455    /// This function is used for iterators.
456    ///
457    /// `offset` is in units of `T`; e.g., a `offset` of 3 represents a pointer
458    /// offset of `3 * size_of::<T>()` bytes.
459    ///
460    /// # Safety
461    ///
462    /// If `mem::size_of::<T>() != 0`, then the safety rules are directly derived
463    /// from the safety rules for [`<*mut T>::sub`] method of `*mut T` and safety
464    /// rules of [`NonNull::new_unchecked`] function.
465    ///
466    /// Thus, in order to uphold the safety contracts for [`<*mut T>::sub`] method
467    /// and [`NonNull::new_unchecked`] function, as well as for the correct
468    /// logic of the work of this crate, the following rules are necessary and
469    /// sufficient:
470    ///
471    /// * `self` contained pointer must not be `dangling`;
472    ///
473    /// * `self.to_base_index() + offset` must not be greater than `RawTableInner.bucket_mask`,
474    ///   i.e. `(self.to_base_index() + offset) <= RawTableInner.bucket_mask` or, in other
475    ///   words, `self.to_base_index() + offset + 1` must be no greater than the number returned
476    ///   by the function [`RawTable::buckets`] or [`RawTableInner::buckets`].
477    ///
478    /// If `mem::size_of::<T>() == 0`, then the only requirement is that the
479    /// `self.to_base_index() + offset` must not be greater than `RawTableInner.bucket_mask`,
480    /// i.e. `(self.to_base_index() + offset) <= RawTableInner.bucket_mask` or, in other words,
481    /// `self.to_base_index() + offset + 1` must be no greater than the number returned by the
482    /// function [`RawTable::buckets`] or [`RawTableInner::buckets`].
483    ///
484    /// [`Bucket`]: crate::raw::Bucket
485    /// [`<*mut T>::sub`]: https://doc.rust-lang.org/core/primitive.pointer.html#method.sub-1
486    /// [`NonNull::new_unchecked`]: https://doc.rust-lang.org/stable/std/ptr/struct.NonNull.html#method.new_unchecked
487    /// [`RawTable::buckets`]: crate::raw::RawTable::buckets
488    /// [`RawTableInner::buckets`]: RawTableInner::buckets
489    #[inline]
490    unsafe fn next_n(&self, offset: usize) -> Self {
491        let ptr = if T::IS_ZERO_SIZED {
492            // invalid pointer is good enough for ZST
493            invalid_mut(self.ptr.as_ptr() as usize + offset)
494        } else {
495            self.ptr.as_ptr().sub(offset)
496        };
497        Self {
498            ptr: NonNull::new_unchecked(ptr),
499        }
500    }
501
502    /// Executes the destructor (if any) of the pointed-to `data`.
503    ///
504    /// # Safety
505    ///
506    /// See [`ptr::drop_in_place`] for safety concerns.
507    ///
508    /// You should use [`RawTable::erase`] instead of this function,
509    /// or be careful with calling this function directly, because for
510    /// properly dropping the data we need also clear `data` control bytes.
511    /// If we drop data, but do not erase `data control byte` it leads to
512    /// double drop when [`RawTable`] goes out of scope.
513    ///
514    /// [`ptr::drop_in_place`]: https://doc.rust-lang.org/core/ptr/fn.drop_in_place.html
515    /// [`RawTable`]: crate::raw::RawTable
516    /// [`RawTable::erase`]: crate::raw::RawTable::erase
517    #[cfg_attr(feature = "inline-more", inline)]
518    pub(crate) unsafe fn drop(&self) {
519        self.as_ptr().drop_in_place();
520    }
521
522    /// Reads the `value` from `self` without moving it. This leaves the
523    /// memory in `self` unchanged.
524    ///
525    /// # Safety
526    ///
527    /// See [`ptr::read`] for safety concerns.
528    ///
529    /// You should use [`RawTable::remove`] instead of this function,
530    /// or be careful with calling this function directly, because compiler
531    /// calls its destructor when the read `value` goes out of scope. It
532    /// can cause double dropping when [`RawTable`] goes out of scope,
533    /// because of not erased `data control byte`.
534    ///
535    /// [`ptr::read`]: https://doc.rust-lang.org/core/ptr/fn.read.html
536    /// [`RawTable`]: crate::raw::RawTable
537    /// [`RawTable::remove`]: crate::raw::RawTable::remove
538    #[inline]
539    pub(crate) unsafe fn read(&self) -> T {
540        self.as_ptr().read()
541    }
542
543    /// Overwrites a memory location with the given `value` without reading
544    /// or dropping the old value (like [`ptr::write`] function).
545    ///
546    /// # Safety
547    ///
548    /// See [`ptr::write`] for safety concerns.
549    ///
550    /// # Note
551    ///
552    /// [`Hash`] and [`Eq`] on the new `T` value and its borrowed form *must* match
553    /// those for the old `T` value, as the map will not re-evaluate where the new
554    /// value should go, meaning the value may become "lost" if their location
555    /// does not reflect their state.
556    ///
557    /// [`ptr::write`]: https://doc.rust-lang.org/core/ptr/fn.write.html
558    /// [`Hash`]: https://doc.rust-lang.org/core/hash/trait.Hash.html
559    /// [`Eq`]: https://doc.rust-lang.org/core/cmp/trait.Eq.html
560    #[inline]
561    pub(crate) unsafe fn write(&self, val: T) {
562        self.as_ptr().write(val);
563    }
564
565    /// Returns a shared immutable reference to the `value`.
566    ///
567    /// # Safety
568    ///
569    /// See [`NonNull::as_ref`] for safety concerns.
570    ///
571    /// [`NonNull::as_ref`]: https://doc.rust-lang.org/core/ptr/struct.NonNull.html#method.as_ref
572    #[inline]
573    pub unsafe fn as_ref<'a>(&self) -> &'a T {
574        &*self.as_ptr()
575    }
576
577    /// Returns a unique mutable reference to the `value`.
578    ///
579    /// # Safety
580    ///
581    /// See [`NonNull::as_mut`] for safety concerns.
582    ///
583    /// # Note
584    ///
585    /// [`Hash`] and [`Eq`] on the new `T` value and its borrowed form *must* match
586    /// those for the old `T` value, as the map will not re-evaluate where the new
587    /// value should go, meaning the value may become "lost" if their location
588    /// does not reflect their state.
589    ///
590    /// [`NonNull::as_mut`]: https://doc.rust-lang.org/core/ptr/struct.NonNull.html#method.as_mut
591    /// [`Hash`]: https://doc.rust-lang.org/core/hash/trait.Hash.html
592    /// [`Eq`]: https://doc.rust-lang.org/core/cmp/trait.Eq.html
593    #[inline]
594    pub unsafe fn as_mut<'a>(&self) -> &'a mut T {
595        &mut *self.as_ptr()
596    }
597}
598
599/// A raw hash table with an unsafe API.
600pub struct RawTable<T, A: Allocator = Global> {
601    table: RawTableInner,
602    alloc: A,
603    // Tell dropck that we own instances of T.
604    marker: PhantomData<T>,
605}
606
607/// Non-generic part of `RawTable` which allows functions to be instantiated only once regardless
608/// of how many different key-value types are used.
609struct RawTableInner {
610    // Mask to get an index from a hash value. The value is one less than the
611    // number of buckets in the table.
612    bucket_mask: usize,
613
614    // [Padding], T_n, ..., T1, T0, C0, C1, ...
615    //                              ^ points here
616    ctrl: NonNull<u8>,
617
618    // Number of elements that can be inserted before we need to grow the table
619    growth_left: usize,
620
621    // Number of elements in the table, only really used by len()
622    items: usize,
623}
624
625impl<T> RawTable<T, Global> {
626    /// Creates a new empty hash table without allocating any memory.
627    ///
628    /// In effect this returns a table with exactly 1 bucket. However we can
629    /// leave the data pointer dangling since that bucket is never written to
630    /// due to our load factor forcing us to always have at least 1 free bucket.
631    #[inline]
632    #[cfg_attr(feature = "rustc-dep-of-std", rustc_const_stable_indirect)]
633    pub const fn new() -> Self {
634        Self {
635            table: RawTableInner::NEW,
636            alloc: Global,
637            marker: PhantomData,
638        }
639    }
640
641    /// Allocates a new hash table with at least enough capacity for inserting
642    /// the given number of elements without reallocating.
643    pub fn with_capacity(capacity: usize) -> Self {
644        Self::with_capacity_in(capacity, Global)
645    }
646}
647
648impl<T, A: Allocator> RawTable<T, A> {
649    const TABLE_LAYOUT: TableLayout = TableLayout::new::<T>();
650
651    /// Creates a new empty hash table without allocating any memory, using the
652    /// given allocator.
653    ///
654    /// In effect this returns a table with exactly 1 bucket. However we can
655    /// leave the data pointer dangling since that bucket is never written to
656    /// due to our load factor forcing us to always have at least 1 free bucket.
657    #[inline]
658    #[cfg_attr(feature = "rustc-dep-of-std", rustc_const_stable_indirect)]
659    pub const fn new_in(alloc: A) -> Self {
660        Self {
661            table: RawTableInner::NEW,
662            alloc,
663            marker: PhantomData,
664        }
665    }
666
667    /// Allocates a new hash table with the given number of buckets.
668    ///
669    /// The control bytes are left uninitialized.
670    #[cfg_attr(feature = "inline-more", inline)]
671    unsafe fn new_uninitialized(
672        alloc: A,
673        buckets: usize,
674        fallibility: Fallibility,
675    ) -> Result<Self, TryReserveError> {
676        debug_assert!(buckets.is_power_of_two());
677
678        Ok(Self {
679            table: RawTableInner::new_uninitialized(
680                &alloc,
681                Self::TABLE_LAYOUT,
682                buckets,
683                fallibility,
684            )?,
685            alloc,
686            marker: PhantomData,
687        })
688    }
689
690    /// Allocates a new hash table using the given allocator, with at least enough capacity for
691    /// inserting the given number of elements without reallocating.
692    pub fn with_capacity_in(capacity: usize, alloc: A) -> Self {
693        Self {
694            table: RawTableInner::with_capacity(&alloc, Self::TABLE_LAYOUT, capacity),
695            alloc,
696            marker: PhantomData,
697        }
698    }
699
700    /// Returns a reference to the underlying allocator.
701    #[inline]
702    pub fn allocator(&self) -> &A {
703        &self.alloc
704    }
705
706    /// Returns pointer to one past last `data` element in the table as viewed from
707    /// the start point of the allocation.
708    ///
709    /// The caller must ensure that the `RawTable` outlives the returned [`NonNull<T>`],
710    /// otherwise using it may result in [`undefined behavior`].
711    ///
712    /// [`undefined behavior`]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
713    #[inline]
714    pub fn data_end(&self) -> NonNull<T> {
715        //                        `self.table.ctrl.cast()` returns pointer that
716        //                        points here (to the end of `T0`)
717        //                          ∨
718        // [Pad], T_n, ..., T1, T0, |CT0, CT1, ..., CT_n|, CTa_0, CTa_1, ..., CTa_m
719        //                           \________  ________/
720        //                                    \/
721        //       `n = buckets - 1`, i.e. `RawTable::buckets() - 1`
722        //
723        // where: T0...T_n  - our stored data;
724        //        CT0...CT_n - control bytes or metadata for `data`.
725        //        CTa_0...CTa_m - additional control bytes, where `m = Group::WIDTH - 1` (so that the search
726        //                        with loading `Group` bytes from the heap works properly, even if the result
727        //                        of `h1(hash) & self.bucket_mask` is equal to `self.bucket_mask`). See also
728        //                        `RawTableInner::set_ctrl` function.
729        //
730        // P.S. `h1(hash) & self.bucket_mask` is the same as `hash as usize % self.buckets()` because the number
731        // of buckets is a power of two, and `self.bucket_mask = self.buckets() - 1`.
732        self.table.ctrl.cast()
733    }
734
735    /// Returns pointer to start of data table.
736    #[inline]
737    #[cfg(feature = "nightly")]
738    pub unsafe fn data_start(&self) -> NonNull<T> {
739        NonNull::new_unchecked(self.data_end().as_ptr().wrapping_sub(self.buckets()))
740    }
741
742    /// Returns the total amount of memory allocated internally by the hash
743    /// table, in bytes.
744    ///
745    /// The returned number is informational only. It is intended to be
746    /// primarily used for memory profiling.
747    #[inline]
748    pub fn allocation_size(&self) -> usize {
749        // SAFETY: We use the same `table_layout` that was used to allocate
750        // this table.
751        unsafe { self.table.allocation_size_or_zero(Self::TABLE_LAYOUT) }
752    }
753
754    /// Returns the index of a bucket from a `Bucket`.
755    #[inline]
756    pub unsafe fn bucket_index(&self, bucket: &Bucket<T>) -> usize {
757        bucket.to_base_index(self.data_end())
758    }
759
760    /// Returns a pointer to an element in the table.
761    ///
762    /// The caller must ensure that the `RawTable` outlives the returned [`Bucket<T>`],
763    /// otherwise using it may result in [`undefined behavior`].
764    ///
765    /// # Safety
766    ///
767    /// If `mem::size_of::<T>() != 0`, then the caller of this function must observe the
768    /// following safety rules:
769    ///
770    /// * The table must already be allocated;
771    ///
772    /// * The `index` must not be greater than the number returned by the [`RawTable::buckets`]
773    ///   function, i.e. `(index + 1) <= self.buckets()`.
774    ///
775    /// It is safe to call this function with index of zero (`index == 0`) on a table that has
776    /// not been allocated, but using the returned [`Bucket`] results in [`undefined behavior`].
777    ///
778    /// If `mem::size_of::<T>() == 0`, then the only requirement is that the `index` must
779    /// not be greater than the number returned by the [`RawTable::buckets`] function, i.e.
780    /// `(index + 1) <= self.buckets()`.
781    ///
782    /// [`RawTable::buckets`]: RawTable::buckets
783    /// [`undefined behavior`]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
784    #[inline]
785    pub unsafe fn bucket(&self, index: usize) -> Bucket<T> {
786        // If mem::size_of::<T>() != 0 then return a pointer to the `element` in the `data part` of the table
787        // (we start counting from "0", so that in the expression T[n], the "n" index actually one less than
788        // the "buckets" number of our `RawTable`, i.e. "n = RawTable::buckets() - 1"):
789        //
790        //           `table.bucket(3).as_ptr()` returns a pointer that points here in the `data`
791        //           part of the `RawTable`, i.e. to the start of T3 (see `Bucket::as_ptr`)
792        //                  |
793        //                  |               `base = self.data_end()` points here
794        //                  |               (to the start of CT0 or to the end of T0)
795        //                  v                 v
796        // [Pad], T_n, ..., |T3|, T2, T1, T0, |CT0, CT1, CT2, CT3, ..., CT_n, CTa_0, CTa_1, ..., CTa_m
797        //                     ^                                              \__________  __________/
798        //        `table.bucket(3)` returns a pointer that points                        \/
799        //         here in the `data` part of the `RawTable` (to              additional control bytes
800        //         the end of T3)                                              `m = Group::WIDTH - 1`
801        //
802        // where: T0...T_n  - our stored data;
803        //        CT0...CT_n - control bytes or metadata for `data`;
804        //        CTa_0...CTa_m - additional control bytes (so that the search with loading `Group` bytes from
805        //                        the heap works properly, even if the result of `h1(hash) & self.table.bucket_mask`
806        //                        is equal to `self.table.bucket_mask`). See also `RawTableInner::set_ctrl` function.
807        //
808        // P.S. `h1(hash) & self.table.bucket_mask` is the same as `hash as usize % self.buckets()` because the number
809        // of buckets is a power of two, and `self.table.bucket_mask = self.buckets() - 1`.
810        debug_assert_ne!(self.table.bucket_mask, 0);
811        debug_assert!(index < self.buckets());
812        Bucket::from_base_index(self.data_end(), index)
813    }
814
815    /// Erases an element from the table without dropping it.
816    #[cfg_attr(feature = "inline-more", inline)]
817    unsafe fn erase_no_drop(&mut self, item: &Bucket<T>) {
818        let index = self.bucket_index(item);
819        self.table.erase(index);
820    }
821
822    /// Erases an element from the table, dropping it in place.
823    #[cfg_attr(feature = "inline-more", inline)]
824    #[allow(clippy::needless_pass_by_value)]
825    pub unsafe fn erase(&mut self, item: Bucket<T>) {
826        // Erase the element from the table first since drop might panic.
827        self.erase_no_drop(&item);
828        item.drop();
829    }
830
831    /// Removes an element from the table, returning it.
832    ///
833    /// This also returns an index to the newly free bucket.
834    #[cfg_attr(feature = "inline-more", inline)]
835    #[allow(clippy::needless_pass_by_value)]
836    pub unsafe fn remove(&mut self, item: Bucket<T>) -> (T, usize) {
837        self.erase_no_drop(&item);
838        (item.read(), self.bucket_index(&item))
839    }
840
841    /// Removes an element from the table, returning it.
842    ///
843    /// This also returns an index to the newly free bucket
844    /// and the former `Tag` for that bucket.
845    #[cfg_attr(feature = "inline-more", inline)]
846    #[allow(clippy::needless_pass_by_value)]
847    pub(crate) unsafe fn remove_tagged(&mut self, item: Bucket<T>) -> (T, usize, Tag) {
848        let index = self.bucket_index(&item);
849        let tag = *self.table.ctrl(index);
850        self.table.erase(index);
851        (item.read(), index, tag)
852    }
853
854    /// Finds and removes an element from the table, returning it.
855    #[cfg_attr(feature = "inline-more", inline)]
856    pub fn remove_entry(&mut self, hash: u64, eq: impl FnMut(&T) -> bool) -> Option<T> {
857        // Avoid `Option::map` because it bloats LLVM IR.
858        match self.find(hash, eq) {
859            Some(bucket) => Some(unsafe { self.remove(bucket).0 }),
860            None => None,
861        }
862    }
863
864    /// Marks all table buckets as empty without dropping their contents.
865    #[cfg_attr(feature = "inline-more", inline)]
866    pub fn clear_no_drop(&mut self) {
867        self.table.clear_no_drop();
868    }
869
870    /// Removes all elements from the table without freeing the backing memory.
871    #[cfg_attr(feature = "inline-more", inline)]
872    pub fn clear(&mut self) {
873        if self.is_empty() {
874            // Special case empty table to avoid surprising O(capacity) time.
875            return;
876        }
877        // Ensure that the table is reset even if one of the drops panic
878        let mut self_ = guard(self, |self_| self_.clear_no_drop());
879        unsafe {
880            // SAFETY: ScopeGuard sets to zero the `items` field of the table
881            // even in case of panic during the dropping of the elements so
882            // that there will be no double drop of the elements.
883            self_.table.drop_elements::<T>();
884        }
885    }
886
887    /// Shrinks the table to fit `max(self.len(), min_size)` elements.
888    #[cfg_attr(feature = "inline-more", inline)]
889    pub fn shrink_to(&mut self, min_size: usize, hasher: impl Fn(&T) -> u64) {
890        // Calculate the minimal number of elements that we need to reserve
891        // space for.
892        let min_size = usize::max(self.table.items, min_size);
893        if min_size == 0 {
894            let mut old_inner = mem::replace(&mut self.table, RawTableInner::NEW);
895            unsafe {
896                // SAFETY:
897                // 1. We call the function only once;
898                // 2. We know for sure that `alloc` and `table_layout` matches the [`Allocator`]
899                //    and [`TableLayout`] that were used to allocate this table.
900                // 3. If any elements' drop function panics, then there will only be a memory leak,
901                //    because we have replaced the inner table with a new one.
902                old_inner.drop_inner_table::<T, _>(&self.alloc, Self::TABLE_LAYOUT);
903            }
904            return;
905        }
906
907        // Calculate the number of buckets that we need for this number of
908        // elements. If the calculation overflows then the requested bucket
909        // count must be larger than what we have right and nothing needs to be
910        // done.
911        let min_buckets = match capacity_to_buckets(min_size, Self::TABLE_LAYOUT) {
912            Some(buckets) => buckets,
913            None => return,
914        };
915
916        // If we have more buckets than we need, shrink the table.
917        if min_buckets < self.buckets() {
918            // Fast path if the table is empty
919            if self.table.items == 0 {
920                let new_inner =
921                    RawTableInner::with_capacity(&self.alloc, Self::TABLE_LAYOUT, min_size);
922                let mut old_inner = mem::replace(&mut self.table, new_inner);
923                unsafe {
924                    // SAFETY:
925                    // 1. We call the function only once;
926                    // 2. We know for sure that `alloc` and `table_layout` matches the [`Allocator`]
927                    //    and [`TableLayout`] that were used to allocate this table.
928                    // 3. If any elements' drop function panics, then there will only be a memory leak,
929                    //    because we have replaced the inner table with a new one.
930                    old_inner.drop_inner_table::<T, _>(&self.alloc, Self::TABLE_LAYOUT);
931                }
932            } else {
933                // Avoid `Result::unwrap_or_else` because it bloats LLVM IR.
934                unsafe {
935                    // SAFETY:
936                    // 1. We know for sure that `min_size >= self.table.items`.
937                    // 2. The [`RawTableInner`] must already have properly initialized control bytes since
938                    //    we will never expose RawTable::new_uninitialized in a public API.
939                    if self
940                        .resize(min_size, hasher, Fallibility::Infallible)
941                        .is_err()
942                    {
943                        // SAFETY: The result of calling the `resize` function cannot be an error
944                        // because `fallibility == Fallibility::Infallible.
945                        hint::unreachable_unchecked()
946                    }
947                }
948            }
949        }
950    }
951
952    /// Ensures that at least `additional` items can be inserted into the table
953    /// without reallocation.
954    #[cfg_attr(feature = "inline-more", inline)]
955    pub fn reserve(&mut self, additional: usize, hasher: impl Fn(&T) -> u64) {
956        if unlikely(additional > self.table.growth_left) {
957            // Avoid `Result::unwrap_or_else` because it bloats LLVM IR.
958            unsafe {
959                // SAFETY: The [`RawTableInner`] must already have properly initialized control
960                // bytes since we will never expose RawTable::new_uninitialized in a public API.
961                if self
962                    .reserve_rehash(additional, hasher, Fallibility::Infallible)
963                    .is_err()
964                {
965                    // SAFETY: All allocation errors will be caught inside `RawTableInner::reserve_rehash`.
966                    hint::unreachable_unchecked()
967                }
968            }
969        }
970    }
971
972    /// Tries to ensure that at least `additional` items can be inserted into
973    /// the table without reallocation.
974    #[cfg_attr(feature = "inline-more", inline)]
975    pub fn try_reserve(
976        &mut self,
977        additional: usize,
978        hasher: impl Fn(&T) -> u64,
979    ) -> Result<(), TryReserveError> {
980        if additional > self.table.growth_left {
981            // SAFETY: The [`RawTableInner`] must already have properly initialized control
982            // bytes since we will never expose RawTable::new_uninitialized in a public API.
983            unsafe { self.reserve_rehash(additional, hasher, Fallibility::Fallible) }
984        } else {
985            Ok(())
986        }
987    }
988
989    /// Out-of-line slow path for `reserve` and `try_reserve`.
990    ///
991    /// # Safety
992    ///
993    /// The [`RawTableInner`] must have properly initialized control bytes,
994    /// otherwise calling this function results in [`undefined behavior`]
995    ///
996    /// [`undefined behavior`]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
997    #[cold]
998    #[inline(never)]
999    unsafe fn reserve_rehash(
1000        &mut self,
1001        additional: usize,
1002        hasher: impl Fn(&T) -> u64,
1003        fallibility: Fallibility,
1004    ) -> Result<(), TryReserveError> {
1005        unsafe {
1006            // SAFETY:
1007            // 1. We know for sure that `alloc` and `layout` matches the [`Allocator`] and
1008            //    [`TableLayout`] that were used to allocate this table.
1009            // 2. The `drop` function is the actual drop function of the elements stored in
1010            //    the table.
1011            // 3. The caller ensures that the control bytes of the `RawTableInner`
1012            //    are already initialized.
1013            self.table.reserve_rehash_inner(
1014                &self.alloc,
1015                additional,
1016                &|table, index| hasher(table.bucket::<T>(index).as_ref()),
1017                fallibility,
1018                Self::TABLE_LAYOUT,
1019                if T::NEEDS_DROP {
1020                    Some(|ptr| ptr::drop_in_place(ptr as *mut T))
1021                } else {
1022                    None
1023                },
1024            )
1025        }
1026    }
1027
1028    /// Allocates a new table of a different size and moves the contents of the
1029    /// current table into it.
1030    ///
1031    /// # Safety
1032    ///
1033    /// The [`RawTableInner`] must have properly initialized control bytes,
1034    /// otherwise calling this function results in [`undefined behavior`]
1035    ///
1036    /// The caller of this function must ensure that `capacity >= self.table.items`
1037    /// otherwise:
1038    ///
1039    /// * If `self.table.items != 0`, calling of this function with `capacity`
1040    ///   equal to 0 (`capacity == 0`) results in [`undefined behavior`].
1041    ///
1042    /// * If `self.table.items > capacity_to_buckets(capacity, Self::TABLE_LAYOUT)`
1043    ///   calling this function are never return (will loop infinitely).
1044    ///
1045    /// See [`RawTableInner::find_insert_index`] for more information.
1046    ///
1047    /// [`RawTableInner::find_insert_index`]: RawTableInner::find_insert_index
1048    /// [`undefined behavior`]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
1049    unsafe fn resize(
1050        &mut self,
1051        capacity: usize,
1052        hasher: impl Fn(&T) -> u64,
1053        fallibility: Fallibility,
1054    ) -> Result<(), TryReserveError> {
1055        // SAFETY:
1056        // 1. The caller of this function guarantees that `capacity >= self.table.items`.
1057        // 2. We know for sure that `alloc` and `layout` matches the [`Allocator`] and
1058        //    [`TableLayout`] that were used to allocate this table.
1059        // 3. The caller ensures that the control bytes of the `RawTableInner`
1060        //    are already initialized.
1061        self.table.resize_inner(
1062            &self.alloc,
1063            capacity,
1064            &|table, index| hasher(table.bucket::<T>(index).as_ref()),
1065            fallibility,
1066            Self::TABLE_LAYOUT,
1067        )
1068    }
1069
1070    /// Inserts a new element into the table, and returns its raw bucket.
1071    ///
1072    /// This does not check if the given element already exists in the table.
1073    #[cfg_attr(feature = "inline-more", inline)]
1074    pub fn insert(&mut self, hash: u64, value: T, hasher: impl Fn(&T) -> u64) -> Bucket<T> {
1075        unsafe {
1076            // SAFETY:
1077            // 1. The [`RawTableInner`] must already have properly initialized control bytes since
1078            //    we will never expose `RawTable::new_uninitialized` in a public API.
1079            //
1080            // 2. We reserve additional space (if necessary) right after calling this function.
1081            let mut index = self.table.find_insert_index(hash);
1082
1083            // We can avoid growing the table once we have reached our load factor if we are replacing
1084            // a tombstone. This works since the number of EMPTY slots does not change in this case.
1085            //
1086            // SAFETY: The function is guaranteed to return an index in the range `0..=self.buckets()`.
1087            let old_ctrl = *self.table.ctrl(index);
1088            if unlikely(self.table.growth_left == 0 && old_ctrl.special_is_empty()) {
1089                self.reserve(1, hasher);
1090                // SAFETY: We know for sure that `RawTableInner` has control bytes
1091                // initialized and that there is extra space in the table.
1092                index = self.table.find_insert_index(hash);
1093            }
1094
1095            self.insert_at_index(hash, index, value)
1096        }
1097    }
1098
1099    /// Inserts a new element into the table, and returns a mutable reference to it.
1100    ///
1101    /// This does not check if the given element already exists in the table.
1102    #[cfg_attr(feature = "inline-more", inline)]
1103    pub fn insert_entry(&mut self, hash: u64, value: T, hasher: impl Fn(&T) -> u64) -> &mut T {
1104        unsafe { self.insert(hash, value, hasher).as_mut() }
1105    }
1106
1107    /// Inserts a new element into the table, without growing the table.
1108    ///
1109    /// There must be enough space in the table to insert the new element.
1110    ///
1111    /// This does not check if the given element already exists in the table.
1112    #[cfg_attr(feature = "inline-more", inline)]
1113    #[cfg(feature = "rustc-internal-api")]
1114    pub unsafe fn insert_no_grow(&mut self, hash: u64, value: T) -> Bucket<T> {
1115        let (index, old_ctrl) = self.table.prepare_insert_index(hash);
1116        let bucket = self.table.bucket(index);
1117
1118        // If we are replacing a DELETED entry then we don't need to update
1119        // the load counter.
1120        self.table.growth_left -= old_ctrl.special_is_empty() as usize;
1121
1122        bucket.write(value);
1123        self.table.items += 1;
1124        bucket
1125    }
1126
1127    /// Temporary removes a bucket, applying the given function to the removed
1128    /// element and optionally put back the returned value in the same bucket.
1129    ///
1130    /// Returns `true` if the bucket still contains an element
1131    ///
1132    /// This does not check if the given bucket is actually occupied.
1133    #[cfg_attr(feature = "inline-more", inline)]
1134    pub unsafe fn replace_bucket_with<F>(&mut self, bucket: Bucket<T>, f: F) -> bool
1135    where
1136        F: FnOnce(T) -> Option<T>,
1137    {
1138        let index = self.bucket_index(&bucket);
1139        let old_ctrl = *self.table.ctrl(index);
1140        debug_assert!(self.is_bucket_full(index));
1141        let old_growth_left = self.table.growth_left;
1142        let item = self.remove(bucket).0;
1143        if let Some(new_item) = f(item) {
1144            self.table.growth_left = old_growth_left;
1145            self.table.set_ctrl(index, old_ctrl);
1146            self.table.items += 1;
1147            self.bucket(index).write(new_item);
1148            true
1149        } else {
1150            false
1151        }
1152    }
1153
1154    /// Searches for an element in the table. If the element is not found,
1155    /// returns `Err` with the position of a slot where an element with the
1156    /// same hash could be inserted.
1157    ///
1158    /// This function may resize the table if additional space is required for
1159    /// inserting an element.
1160    #[inline]
1161    pub fn find_or_find_insert_index(
1162        &mut self,
1163        hash: u64,
1164        mut eq: impl FnMut(&T) -> bool,
1165        hasher: impl Fn(&T) -> u64,
1166    ) -> Result<Bucket<T>, usize> {
1167        self.reserve(1, hasher);
1168
1169        unsafe {
1170            // SAFETY:
1171            // 1. We know for sure that there is at least one empty `bucket` in the table.
1172            // 2. The [`RawTableInner`] must already have properly initialized control bytes since we will
1173            //    never expose `RawTable::new_uninitialized` in a public API.
1174            // 3. The `find_or_find_insert_index_inner` function returns the `index` of only the full bucket,
1175            //    which is in the range `0..self.buckets()` (since there is at least one empty `bucket` in
1176            //    the table), so calling `self.bucket(index)` and `Bucket::as_ref` is safe.
1177            match self
1178                .table
1179                .find_or_find_insert_index_inner(hash, &mut |index| eq(self.bucket(index).as_ref()))
1180            {
1181                // SAFETY: See explanation above.
1182                Ok(index) => Ok(self.bucket(index)),
1183                Err(index) => Err(index),
1184            }
1185        }
1186    }
1187
1188    /// Inserts a new element into the table at the given index with the given hash,
1189    /// and returns its raw bucket.
1190    ///
1191    /// # Safety
1192    ///
1193    /// `index` must point to a slot previously returned by
1194    /// `find_or_find_insert_index`, and no mutation of the table must have
1195    /// occurred since that call.
1196    #[inline]
1197    pub unsafe fn insert_at_index(&mut self, hash: u64, index: usize, value: T) -> Bucket<T> {
1198        self.insert_tagged_at_index(Tag::full(hash), index, value)
1199    }
1200
1201    /// Inserts a new element into the table at the given index with the given tag,
1202    /// and returns its raw bucket.
1203    ///
1204    /// # Safety
1205    ///
1206    /// `index` must point to a slot previously returned by
1207    /// `find_or_find_insert_index`, and no mutation of the table must have
1208    /// occurred since that call.
1209    #[inline]
1210    pub(crate) unsafe fn insert_tagged_at_index(
1211        &mut self,
1212        tag: Tag,
1213        index: usize,
1214        value: T,
1215    ) -> Bucket<T> {
1216        let old_ctrl = *self.table.ctrl(index);
1217        self.table.record_item_insert_at(index, old_ctrl, tag);
1218
1219        let bucket = self.bucket(index);
1220        bucket.write(value);
1221        bucket
1222    }
1223
1224    /// Searches for an element in the table.
1225    #[inline]
1226    pub fn find(&self, hash: u64, mut eq: impl FnMut(&T) -> bool) -> Option<Bucket<T>> {
1227        unsafe {
1228            // SAFETY:
1229            // 1. The [`RawTableInner`] must already have properly initialized control bytes since we
1230            //    will never expose `RawTable::new_uninitialized` in a public API.
1231            // 1. The `find_inner` function returns the `index` of only the full bucket, which is in
1232            //    the range `0..self.buckets()`, so calling `self.bucket(index)` and `Bucket::as_ref`
1233            //    is safe.
1234            let result = self
1235                .table
1236                .find_inner(hash, &mut |index| eq(self.bucket(index).as_ref()));
1237
1238            // Avoid `Option::map` because it bloats LLVM IR.
1239            match result {
1240                // SAFETY: See explanation above.
1241                Some(index) => Some(self.bucket(index)),
1242                None => None,
1243            }
1244        }
1245    }
1246
1247    /// Gets a reference to an element in the table.
1248    #[inline]
1249    pub fn get(&self, hash: u64, eq: impl FnMut(&T) -> bool) -> Option<&T> {
1250        // Avoid `Option::map` because it bloats LLVM IR.
1251        match self.find(hash, eq) {
1252            Some(bucket) => Some(unsafe { bucket.as_ref() }),
1253            None => None,
1254        }
1255    }
1256
1257    /// Gets a mutable reference to an element in the table.
1258    #[inline]
1259    pub fn get_mut(&mut self, hash: u64, eq: impl FnMut(&T) -> bool) -> Option<&mut T> {
1260        // Avoid `Option::map` because it bloats LLVM IR.
1261        match self.find(hash, eq) {
1262            Some(bucket) => Some(unsafe { bucket.as_mut() }),
1263            None => None,
1264        }
1265    }
1266
1267    /// Gets a reference to an element in the table at the given bucket index.
1268    #[inline]
1269    pub fn get_bucket(&self, index: usize) -> Option<&T> {
1270        unsafe {
1271            if index < self.buckets() && self.is_bucket_full(index) {
1272                Some(self.bucket(index).as_ref())
1273            } else {
1274                None
1275            }
1276        }
1277    }
1278
1279    /// Gets a mutable reference to an element in the table at the given bucket index.
1280    #[inline]
1281    pub fn get_bucket_mut(&mut self, index: usize) -> Option<&mut T> {
1282        unsafe {
1283            if index < self.buckets() && self.is_bucket_full(index) {
1284                Some(self.bucket(index).as_mut())
1285            } else {
1286                None
1287            }
1288        }
1289    }
1290
1291    /// Returns a pointer to an element in the table, but only after verifying that
1292    /// the index is in-bounds and the bucket is occupied.
1293    #[inline]
1294    pub fn checked_bucket(&self, index: usize) -> Option<Bucket<T>> {
1295        unsafe {
1296            if index < self.buckets() && self.is_bucket_full(index) {
1297                Some(self.bucket(index))
1298            } else {
1299                None
1300            }
1301        }
1302    }
1303
1304    /// Attempts to get mutable references to `N` entries in the table at once.
1305    ///
1306    /// Returns an array of length `N` with the results of each query.
1307    ///
1308    /// At most one mutable reference will be returned to any entry. `None` will be returned if any
1309    /// of the hashes are duplicates. `None` will be returned if the hash is not found.
1310    ///
1311    /// The `eq` argument should be a closure such that `eq(i, k)` returns true if `k` is equal to
1312    /// the `i`th key to be looked up.
1313    pub fn get_disjoint_mut<const N: usize>(
1314        &mut self,
1315        hashes: [u64; N],
1316        eq: impl FnMut(usize, &T) -> bool,
1317    ) -> [Option<&'_ mut T>; N] {
1318        unsafe {
1319            let ptrs = self.get_disjoint_mut_pointers(hashes, eq);
1320
1321            for (i, cur) in ptrs.iter().enumerate() {
1322                if cur.is_some() && ptrs[..i].contains(cur) {
1323                    panic!("duplicate keys found");
1324                }
1325            }
1326            // All bucket are distinct from all previous buckets so we're clear to return the result
1327            // of the lookup.
1328
1329            ptrs.map(|ptr| ptr.map(|mut ptr| ptr.as_mut()))
1330        }
1331    }
1332
1333    pub unsafe fn get_disjoint_unchecked_mut<const N: usize>(
1334        &mut self,
1335        hashes: [u64; N],
1336        eq: impl FnMut(usize, &T) -> bool,
1337    ) -> [Option<&'_ mut T>; N] {
1338        let ptrs = self.get_disjoint_mut_pointers(hashes, eq);
1339        ptrs.map(|ptr| ptr.map(|mut ptr| ptr.as_mut()))
1340    }
1341
1342    unsafe fn get_disjoint_mut_pointers<const N: usize>(
1343        &mut self,
1344        hashes: [u64; N],
1345        mut eq: impl FnMut(usize, &T) -> bool,
1346    ) -> [Option<NonNull<T>>; N] {
1347        array::from_fn(|i| {
1348            self.find(hashes[i], |k| eq(i, k))
1349                .map(|cur| cur.as_non_null())
1350        })
1351    }
1352
1353    /// Returns the number of elements the map can hold without reallocating.
1354    ///
1355    /// This number is a lower bound; the table might be able to hold
1356    /// more, but is guaranteed to be able to hold at least this many.
1357    #[inline]
1358    pub fn capacity(&self) -> usize {
1359        self.table.items + self.table.growth_left
1360    }
1361
1362    /// Returns the number of elements in the table.
1363    #[inline]
1364    pub fn len(&self) -> usize {
1365        self.table.items
1366    }
1367
1368    /// Returns `true` if the table contains no elements.
1369    #[inline]
1370    pub fn is_empty(&self) -> bool {
1371        self.len() == 0
1372    }
1373
1374    /// Returns the number of buckets in the table.
1375    #[inline]
1376    pub fn buckets(&self) -> usize {
1377        self.table.bucket_mask + 1
1378    }
1379
1380    /// Checks whether the bucket at `index` is full.
1381    ///
1382    /// # Safety
1383    ///
1384    /// The caller must ensure `index` is less than the number of buckets.
1385    #[inline]
1386    pub unsafe fn is_bucket_full(&self, index: usize) -> bool {
1387        self.table.is_bucket_full(index)
1388    }
1389
1390    /// Returns an iterator over every element in the table. It is up to
1391    /// the caller to ensure that the `RawTable` outlives the `RawIter`.
1392    /// Because we cannot make the `next` method unsafe on the `RawIter`
1393    /// struct, we have to make the `iter` method unsafe.
1394    #[inline]
1395    pub unsafe fn iter(&self) -> RawIter<T> {
1396        // SAFETY:
1397        // 1. The caller must uphold the safety contract for `iter` method.
1398        // 2. The [`RawTableInner`] must already have properly initialized control bytes since
1399        //    we will never expose RawTable::new_uninitialized in a public API.
1400        self.table.iter()
1401    }
1402
1403    /// Returns an iterator over occupied buckets that could match a given hash.
1404    ///
1405    /// `RawTable` only stores 7 bits of the hash value, so this iterator may
1406    /// return items that have a hash value different than the one provided. You
1407    /// should always validate the returned values before using them.
1408    ///
1409    /// It is up to the caller to ensure that the `RawTable` outlives the
1410    /// `RawIterHash`. Because we cannot make the `next` method unsafe on the
1411    /// `RawIterHash` struct, we have to make the `iter_hash` method unsafe.
1412    #[cfg_attr(feature = "inline-more", inline)]
1413    pub unsafe fn iter_hash(&self, hash: u64) -> RawIterHash<T> {
1414        RawIterHash::new(self, hash)
1415    }
1416
1417    /// Returns an iterator over occupied bucket indices that could match a given hash.
1418    ///
1419    /// `RawTable` only stores 7 bits of the hash value, so this iterator may
1420    /// return items that have a hash value different than the one provided. You
1421    /// should always validate the returned values before using them.
1422    ///
1423    /// It is up to the caller to ensure that the `RawTable` outlives the
1424    /// `RawIterHashIndices`. Because we cannot make the `next` method unsafe on the
1425    /// `RawIterHashIndices` struct, we have to make the `iter_hash_buckets` method unsafe.
1426    #[cfg_attr(feature = "inline-more", inline)]
1427    pub(crate) unsafe fn iter_hash_buckets(&self, hash: u64) -> RawIterHashIndices {
1428        RawIterHashIndices::new(&self.table, hash)
1429    }
1430
1431    /// Returns an iterator over full buckets indices in the table.
1432    ///
1433    /// See [`RawTableInner::full_buckets_indices`] for safety conditions.
1434    #[inline(always)]
1435    pub(crate) unsafe fn full_buckets_indices(&self) -> FullBucketsIndices {
1436        self.table.full_buckets_indices()
1437    }
1438
1439    /// Returns an iterator which removes all elements from the table without
1440    /// freeing the memory.
1441    #[cfg_attr(feature = "inline-more", inline)]
1442    pub fn drain(&mut self) -> RawDrain<'_, T, A> {
1443        unsafe {
1444            let iter = self.iter();
1445            self.drain_iter_from(iter)
1446        }
1447    }
1448
1449    /// Returns an iterator which removes all elements from the table without
1450    /// freeing the memory.
1451    ///
1452    /// Iteration starts at the provided iterator's current location.
1453    ///
1454    /// It is up to the caller to ensure that the iterator is valid for this
1455    /// `RawTable` and covers all items that remain in the table.
1456    #[cfg_attr(feature = "inline-more", inline)]
1457    pub unsafe fn drain_iter_from(&mut self, iter: RawIter<T>) -> RawDrain<'_, T, A> {
1458        debug_assert_eq!(iter.len(), self.len());
1459        RawDrain {
1460            iter,
1461            table: mem::replace(&mut self.table, RawTableInner::NEW),
1462            orig_table: NonNull::from(&mut self.table),
1463            marker: PhantomData,
1464        }
1465    }
1466
1467    /// Returns an iterator which consumes all elements from the table.
1468    ///
1469    /// Iteration starts at the provided iterator's current location.
1470    ///
1471    /// It is up to the caller to ensure that the iterator is valid for this
1472    /// `RawTable` and covers all items that remain in the table.
1473    pub unsafe fn into_iter_from(self, iter: RawIter<T>) -> RawIntoIter<T, A> {
1474        debug_assert_eq!(iter.len(), self.len());
1475
1476        let allocation = self.into_allocation();
1477        RawIntoIter {
1478            iter,
1479            allocation,
1480            marker: PhantomData,
1481        }
1482    }
1483
1484    /// Converts the table into a raw allocation. The contents of the table
1485    /// should be dropped using a `RawIter` before freeing the allocation.
1486    #[cfg_attr(feature = "inline-more", inline)]
1487    pub(crate) fn into_allocation(self) -> Option<(NonNull<u8>, Layout, A)> {
1488        let alloc = if self.table.is_empty_singleton() {
1489            None
1490        } else {
1491            // Avoid `Option::unwrap_or_else` because it bloats LLVM IR.
1492            let (layout, ctrl_offset) =
1493                match Self::TABLE_LAYOUT.calculate_layout_for(self.table.buckets()) {
1494                    Some(lco) => lco,
1495                    None => unsafe { hint::unreachable_unchecked() },
1496                };
1497            Some((
1498                unsafe { NonNull::new_unchecked(self.table.ctrl.as_ptr().sub(ctrl_offset).cast()) },
1499                layout,
1500                unsafe { ptr::read(&self.alloc) },
1501            ))
1502        };
1503        mem::forget(self);
1504        alloc
1505    }
1506}
1507
1508unsafe impl<T, A: Allocator> Send for RawTable<T, A>
1509where
1510    T: Send,
1511    A: Send,
1512{
1513}
1514unsafe impl<T, A: Allocator> Sync for RawTable<T, A>
1515where
1516    T: Sync,
1517    A: Sync,
1518{
1519}
1520
1521impl RawTableInner {
1522    const NEW: Self = RawTableInner::new();
1523
1524    /// Creates a new empty hash table without allocating any memory.
1525    ///
1526    /// In effect this returns a table with exactly 1 bucket. However we can
1527    /// leave the data pointer dangling since that bucket is never accessed
1528    /// due to our load factor forcing us to always have at least 1 free bucket.
1529    #[inline]
1530    const fn new() -> Self {
1531        Self {
1532            // Be careful to cast the entire slice to a raw pointer.
1533            ctrl: unsafe {
1534                NonNull::new_unchecked(Group::static_empty().as_ptr().cast_mut().cast())
1535            },
1536            bucket_mask: 0,
1537            items: 0,
1538            growth_left: 0,
1539        }
1540    }
1541}
1542
1543/// Find the previous power of 2. If it's already a power of 2, it's unchanged.
1544/// Passing zero is undefined behavior.
1545pub(crate) fn prev_pow2(z: usize) -> usize {
1546    let shift = mem::size_of::<usize>() * 8 - 1;
1547    1 << (shift - (z.leading_zeros() as usize))
1548}
1549
1550/// Finds the largest number of buckets that can fit in `allocation_size`
1551/// provided the given TableLayout.
1552///
1553/// This relies on some invariants of `capacity_to_buckets`, so only feed in
1554/// an `allocation_size` calculated from `capacity_to_buckets`.
1555fn maximum_buckets_in(
1556    allocation_size: usize,
1557    table_layout: TableLayout,
1558    group_width: usize,
1559) -> usize {
1560    // Given an equation like:
1561    //   z >= x * y + x + g
1562    // x can be maximized by doing:
1563    //   x = (z - g) / (y + 1)
1564    // If you squint:
1565    //   x is the number of buckets
1566    //   y is the table_layout.size
1567    //   z is the size of the allocation
1568    //   g is the group width
1569    // But this is ignoring the padding needed for ctrl_align.
1570    // If we remember these restrictions:
1571    //   x is always a power of 2
1572    //   Layout size for T must always be a multiple of T
1573    // Then the alignment can be ignored if we add the constraint:
1574    //   x * y >= table_layout.ctrl_align
1575    // This is taken care of by `capacity_to_buckets`.
1576    // It may be helpful to understand this if you remember that:
1577    //   ctrl_offset = align(x * y, ctrl_align)
1578    let x = (allocation_size - group_width) / (table_layout.size + 1);
1579    prev_pow2(x)
1580}
1581
1582impl RawTableInner {
1583    /// Allocates a new [`RawTableInner`] with the given number of buckets.
1584    /// The control bytes and buckets are left uninitialized.
1585    ///
1586    /// # Safety
1587    ///
1588    /// The caller of this function must ensure that the `buckets` is power of two
1589    /// and also initialize all control bytes of the length `self.bucket_mask + 1 +
1590    /// Group::WIDTH` with the [`Tag::EMPTY`] bytes.
1591    ///
1592    /// See also [`Allocator`] API for other safety concerns.
1593    ///
1594    /// [`Allocator`]: https://doc.rust-lang.org/alloc/alloc/trait.Allocator.html
1595    #[cfg_attr(feature = "inline-more", inline)]
1596    unsafe fn new_uninitialized<A>(
1597        alloc: &A,
1598        table_layout: TableLayout,
1599        mut buckets: usize,
1600        fallibility: Fallibility,
1601    ) -> Result<Self, TryReserveError>
1602    where
1603        A: Allocator,
1604    {
1605        debug_assert!(buckets.is_power_of_two());
1606
1607        // Avoid `Option::ok_or_else` because it bloats LLVM IR.
1608        let (layout, mut ctrl_offset) = match table_layout.calculate_layout_for(buckets) {
1609            Some(lco) => lco,
1610            None => return Err(fallibility.capacity_overflow()),
1611        };
1612
1613        let ptr: NonNull<u8> = match do_alloc(alloc, layout) {
1614            Ok(block) => {
1615                // The allocator can't return a value smaller than was
1616                // requested, so this can be != instead of >=.
1617                if block.len() != layout.size() {
1618                    // Utilize over-sized allocations.
1619                    let x = maximum_buckets_in(block.len(), table_layout, Group::WIDTH);
1620                    debug_assert!(x >= buckets);
1621                    // Calculate the new ctrl_offset.
1622                    let (oversized_layout, oversized_ctrl_offset) =
1623                        match table_layout.calculate_layout_for(x) {
1624                            Some(lco) => lco,
1625                            None => unsafe { hint::unreachable_unchecked() },
1626                        };
1627                    debug_assert!(oversized_layout.size() <= block.len());
1628                    debug_assert!(oversized_ctrl_offset >= ctrl_offset);
1629                    ctrl_offset = oversized_ctrl_offset;
1630                    buckets = x;
1631                }
1632
1633                block.cast()
1634            }
1635            Err(_) => return Err(fallibility.alloc_err(layout)),
1636        };
1637
1638        // SAFETY: null pointer will be caught in above check
1639        let ctrl = NonNull::new_unchecked(ptr.as_ptr().add(ctrl_offset));
1640        Ok(Self {
1641            ctrl,
1642            bucket_mask: buckets - 1,
1643            items: 0,
1644            growth_left: bucket_mask_to_capacity(buckets - 1),
1645        })
1646    }
1647
1648    /// Attempts to allocate a new [`RawTableInner`] with at least enough
1649    /// capacity for inserting the given number of elements without reallocating.
1650    ///
1651    /// All the control bytes are initialized with the [`Tag::EMPTY`] bytes.
1652    #[inline]
1653    fn fallible_with_capacity<A>(
1654        alloc: &A,
1655        table_layout: TableLayout,
1656        capacity: usize,
1657        fallibility: Fallibility,
1658    ) -> Result<Self, TryReserveError>
1659    where
1660        A: Allocator,
1661    {
1662        if capacity == 0 {
1663            Ok(Self::NEW)
1664        } else {
1665            // SAFETY: We checked that we could successfully allocate the new table, and then
1666            // initialized all control bytes with the constant `Tag::EMPTY` byte.
1667            unsafe {
1668                let buckets = capacity_to_buckets(capacity, table_layout)
1669                    .ok_or_else(|| fallibility.capacity_overflow())?;
1670
1671                let mut result =
1672                    Self::new_uninitialized(alloc, table_layout, buckets, fallibility)?;
1673                // SAFETY: We checked that the table is allocated and therefore the table already has
1674                // `self.bucket_mask + 1 + Group::WIDTH` number of control bytes (see TableLayout::calculate_layout_for)
1675                // so writing `self.num_ctrl_bytes() == bucket_mask + 1 + Group::WIDTH` bytes is safe.
1676                result.ctrl_slice().fill_empty();
1677
1678                Ok(result)
1679            }
1680        }
1681    }
1682
1683    /// Allocates a new [`RawTableInner`] with at least enough capacity for inserting
1684    /// the given number of elements without reallocating.
1685    ///
1686    /// Panics if the new capacity exceeds [`isize::MAX`] bytes and [`abort`] the program
1687    /// in case of allocation error. Use [`fallible_with_capacity`] instead if you want to
1688    /// handle memory allocation failure.
1689    ///
1690    /// All the control bytes are initialized with the [`Tag::EMPTY`] bytes.
1691    ///
1692    /// [`fallible_with_capacity`]: RawTableInner::fallible_with_capacity
1693    /// [`abort`]: https://doc.rust-lang.org/alloc/alloc/fn.handle_alloc_error.html
1694    fn with_capacity<A>(alloc: &A, table_layout: TableLayout, capacity: usize) -> Self
1695    where
1696        A: Allocator,
1697    {
1698        // Avoid `Result::unwrap_or_else` because it bloats LLVM IR.
1699        match Self::fallible_with_capacity(alloc, table_layout, capacity, Fallibility::Infallible) {
1700            Ok(table_inner) => table_inner,
1701            // SAFETY: All allocation errors will be caught inside `RawTableInner::new_uninitialized`.
1702            Err(_) => unsafe { hint::unreachable_unchecked() },
1703        }
1704    }
1705
1706    /// Fixes up an insertion index returned by the [`RawTableInner::find_insert_index_in_group`] method.
1707    ///
1708    /// In tables smaller than the group width (`self.buckets() < Group::WIDTH`), trailing control
1709    /// bytes outside the range of the table are filled with [`Tag::EMPTY`] entries. These will unfortunately
1710    /// trigger a match of [`RawTableInner::find_insert_index_in_group`] function. This is because
1711    /// the `Some(bit)` returned by `group.match_empty_or_deleted().lowest_set_bit()` after masking
1712    /// (`(probe_seq.pos + bit) & self.bucket_mask`) may point to a full bucket that is already occupied.
1713    /// We detect this situation here and perform a second scan starting at the beginning of the table.
1714    /// This second scan is guaranteed to find an empty slot (due to the load factor) before hitting the
1715    /// trailing control bytes (containing [`Tag::EMPTY`] bytes).
1716    ///
1717    /// If this function is called correctly, it is guaranteed to return an index of an empty or
1718    /// deleted bucket in the range `0..self.buckets()` (see `Warning` and `Safety`).
1719    ///
1720    /// # Warning
1721    ///
1722    /// The table must have at least 1 empty or deleted `bucket`, otherwise if the table is less than
1723    /// the group width (`self.buckets() < Group::WIDTH`) this function returns an index outside of the
1724    /// table indices range `0..self.buckets()` (`0..=self.bucket_mask`). Attempt to write data at that
1725    /// index will cause immediate [`undefined behavior`].
1726    ///
1727    /// # Safety
1728    ///
1729    /// The safety rules are directly derived from the safety rules for [`RawTableInner::ctrl`] method.
1730    /// Thus, in order to uphold those safety contracts, as well as for the correct logic of the work
1731    /// of this crate, the following rules are necessary and sufficient:
1732    ///
1733    /// * The [`RawTableInner`] must have properly initialized control bytes otherwise calling this
1734    ///   function results in [`undefined behavior`].
1735    ///
1736    /// * This function must only be used on insertion indices found by [`RawTableInner::find_insert_index_in_group`]
1737    ///   (after the `find_insert_index_in_group` function, but before insertion into the table).
1738    ///
1739    /// * The `index` must not be greater than the `self.bucket_mask`, i.e. `(index + 1) <= self.buckets()`
1740    ///   (this one is provided by the [`RawTableInner::find_insert_index_in_group`] function).
1741    ///
1742    /// Calling this function with an index not provided by [`RawTableInner::find_insert_index_in_group`]
1743    /// may result in [`undefined behavior`] even if the index satisfies the safety rules of the
1744    /// [`RawTableInner::ctrl`] function (`index < self.bucket_mask + 1 + Group::WIDTH`).
1745    ///
1746    /// [`RawTableInner::ctrl`]: RawTableInner::ctrl
1747    /// [`RawTableInner::find_insert_index_in_group`]: RawTableInner::find_insert_index_in_group
1748    /// [`undefined behavior`]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
1749    #[inline]
1750    unsafe fn fix_insert_index(&self, mut index: usize) -> usize {
1751        // SAFETY: The caller of this function ensures that `index` is in the range `0..=self.bucket_mask`.
1752        if unlikely(self.is_bucket_full(index)) {
1753            debug_assert!(self.bucket_mask < Group::WIDTH);
1754            // SAFETY:
1755            //
1756            // * Since the caller of this function ensures that the control bytes are properly
1757            //   initialized and `ptr = self.ctrl(0)` points to the start of the array of control
1758            //   bytes, therefore: `ctrl` is valid for reads, properly aligned to `Group::WIDTH`
1759            //   and points to the properly initialized control bytes (see also
1760            //   `TableLayout::calculate_layout_for` and `ptr::read`);
1761            //
1762            // * Because the caller of this function ensures that the index was provided by the
1763            //   `self.find_insert_index_in_group()` function, so for for tables larger than the
1764            //   group width (self.buckets() >= Group::WIDTH), we will never end up in the given
1765            //   branch, since `(probe_seq.pos + bit) & self.bucket_mask` in `find_insert_index_in_group`
1766            //   cannot return a full bucket index. For tables smaller than the group width, calling
1767            //   the `unwrap_unchecked` function is also safe, as the trailing control bytes outside
1768            //   the range of the table are filled with EMPTY bytes (and we know for sure that there
1769            //   is at least one FULL bucket), so this second scan either finds an empty slot (due to
1770            //   the load factor) or hits the trailing control bytes (containing EMPTY).
1771            index = Group::load_aligned(self.ctrl(0))
1772                .match_empty_or_deleted()
1773                .lowest_set_bit()
1774                .unwrap_unchecked();
1775        }
1776        index
1777    }
1778
1779    /// Finds the position to insert something in a group.
1780    ///
1781    /// **This may have false positives and must be fixed up with `fix_insert_index`
1782    /// before it's used.**
1783    ///
1784    /// The function is guaranteed to return the index of an empty or deleted [`Bucket`]
1785    /// in the range `0..self.buckets()` (`0..=self.bucket_mask`).
1786    #[inline]
1787    fn find_insert_index_in_group(&self, group: &Group, probe_seq: &ProbeSeq) -> Option<usize> {
1788        let bit = group.match_empty_or_deleted().lowest_set_bit();
1789
1790        if likely(bit.is_some()) {
1791            // This is the same as `(probe_seq.pos + bit) % self.buckets()` because the number
1792            // of buckets is a power of two, and `self.bucket_mask = self.buckets() - 1`.
1793            Some((probe_seq.pos + bit.unwrap()) & self.bucket_mask)
1794        } else {
1795            None
1796        }
1797    }
1798
1799    /// Searches for an element in the table, or a potential slot where that element could
1800    /// be inserted (an empty or deleted [`Bucket`] index).
1801    ///
1802    /// This uses dynamic dispatch to reduce the amount of code generated, but that is
1803    /// eliminated by LLVM optimizations.
1804    ///
1805    /// This function does not make any changes to the `data` part of the table, or any
1806    /// changes to the `items` or `growth_left` field of the table.
1807    ///
1808    /// The table must have at least 1 empty or deleted `bucket`, otherwise, if the
1809    /// `eq: &mut dyn FnMut(usize) -> bool` function does not return `true`, this function
1810    /// will never return (will go into an infinite loop) for tables larger than the group
1811    /// width, or return an index outside of the table indices range if the table is less
1812    /// than the group width.
1813    ///
1814    /// This function is guaranteed to provide the `eq: &mut dyn FnMut(usize) -> bool`
1815    /// function with only `FULL` buckets' indices and return the `index` of the found
1816    /// element (as `Ok(index)`). If the element is not found and there is at least 1
1817    /// empty or deleted [`Bucket`] in the table, the function is guaranteed to return
1818    /// an index in the range `0..self.buckets()`, but in any case, if this function
1819    /// returns `Err`, it will contain an index in the range `0..=self.buckets()`.
1820    ///
1821    /// # Safety
1822    ///
1823    /// The [`RawTableInner`] must have properly initialized control bytes otherwise calling
1824    /// this function results in [`undefined behavior`].
1825    ///
1826    /// Attempt to write data at the index returned by this function when the table is less than
1827    /// the group width and if there was not at least one empty or deleted bucket in the table
1828    /// will cause immediate [`undefined behavior`]. This is because in this case the function
1829    /// will return `self.bucket_mask + 1` as an index due to the trailing [`Tag::EMPTY`] control
1830    /// bytes outside the table range.
1831    ///
1832    /// [`undefined behavior`]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
1833    #[inline]
1834    unsafe fn find_or_find_insert_index_inner(
1835        &self,
1836        hash: u64,
1837        eq: &mut dyn FnMut(usize) -> bool,
1838    ) -> Result<usize, usize> {
1839        let mut insert_index = None;
1840
1841        let tag_hash = Tag::full(hash);
1842        let mut probe_seq = self.probe_seq(hash);
1843
1844        loop {
1845            // SAFETY:
1846            // * Caller of this function ensures that the control bytes are properly initialized.
1847            //
1848            // * `ProbeSeq.pos` cannot be greater than `self.bucket_mask = self.buckets() - 1`
1849            //   of the table due to masking with `self.bucket_mask` and also because the number
1850            //   of buckets is a power of two (see `self.probe_seq` function).
1851            //
1852            // * Even if `ProbeSeq.pos` returns `position == self.bucket_mask`, it is safe to
1853            //   call `Group::load` due to the extended control bytes range, which is
1854            //  `self.bucket_mask + 1 + Group::WIDTH` (in fact, this means that the last control
1855            //   byte will never be read for the allocated table);
1856            //
1857            // * Also, even if `RawTableInner` is not already allocated, `ProbeSeq.pos` will
1858            //   always return "0" (zero), so Group::load will read unaligned `Group::static_empty()`
1859            //   bytes, which is safe (see RawTableInner::new).
1860            let group = unsafe { Group::load(self.ctrl(probe_seq.pos)) };
1861
1862            for bit in group.match_tag(tag_hash) {
1863                let index = (probe_seq.pos + bit) & self.bucket_mask;
1864
1865                if likely(eq(index)) {
1866                    return Ok(index);
1867                }
1868            }
1869
1870            // We didn't find the element we were looking for in the group, try to get an
1871            // insertion slot from the group if we don't have one yet.
1872            if likely(insert_index.is_none()) {
1873                insert_index = self.find_insert_index_in_group(&group, &probe_seq);
1874            }
1875
1876            if let Some(insert_index) = insert_index {
1877                // Only stop the search if the group contains at least one empty element.
1878                // Otherwise, the element that we are looking for might be in a following group.
1879                if likely(group.match_empty().any_bit_set()) {
1880                    // We must have found a insert slot by now, since the current group contains at
1881                    // least one. For tables smaller than the group width, there will still be an
1882                    // empty element in the current (and only) group due to the load factor.
1883                    unsafe {
1884                        // SAFETY:
1885                        // * Caller of this function ensures that the control bytes are properly initialized.
1886                        //
1887                        // * We use this function with the index found by `self.find_insert_index_in_group`
1888                        return Err(self.fix_insert_index(insert_index));
1889                    }
1890                }
1891            }
1892
1893            probe_seq.move_next(self.bucket_mask);
1894        }
1895    }
1896
1897    /// Searches for an empty or deleted bucket which is suitable for inserting a new
1898    /// element and sets the hash for that slot. Returns an index of that slot and the
1899    /// old control byte stored in the found index.
1900    ///
1901    /// This function does not check if the given element exists in the table. Also,
1902    /// this function does not check if there is enough space in the table to insert
1903    /// a new element. The caller of the function must make sure that the table has at
1904    /// least 1 empty or deleted `bucket`, otherwise this function will never return
1905    /// (will go into an infinite loop) for tables larger than the group width, or
1906    /// return an index outside of the table indices range if the table is less than
1907    /// the group width.
1908    ///
1909    /// If there is at least 1 empty or deleted `bucket` in the table, the function is
1910    /// guaranteed to return an `index` in the range `0..self.buckets()`, but in any case,
1911    /// if this function returns an `index` it will be in the range `0..=self.buckets()`.
1912    ///
1913    /// This function does not make any changes to the `data` parts of the table,
1914    /// or any changes to the `items` or `growth_left` field of the table.
1915    ///
1916    /// # Safety
1917    ///
1918    /// The safety rules are directly derived from the safety rules for the
1919    /// [`RawTableInner::set_ctrl_hash`] and [`RawTableInner::find_insert_index`] methods.
1920    /// Thus, in order to uphold the safety contracts for that methods, as well as for
1921    /// the correct logic of the work of this crate, you must observe the following rules
1922    /// when calling this function:
1923    ///
1924    /// * The [`RawTableInner`] has already been allocated and has properly initialized
1925    ///   control bytes otherwise calling this function results in [`undefined behavior`].
1926    ///
1927    /// * The caller of this function must ensure that the "data" parts of the table
1928    ///   will have an entry in the returned index (matching the given hash) right
1929    ///   after calling this function.
1930    ///
1931    /// Attempt to write data at the `index` returned by this function when the table is
1932    /// less than the group width and if there was not at least one empty or deleted bucket in
1933    /// the table will cause immediate [`undefined behavior`]. This is because in this case the
1934    /// function will return `self.bucket_mask + 1` as an index due to the trailing [`Tag::EMPTY`]
1935    /// control bytes outside the table range.
1936    ///
1937    /// The caller must independently increase the `items` field of the table, and also,
1938    /// if the old control byte was [`Tag::EMPTY`], then decrease the table's `growth_left`
1939    /// field, and do not change it if the old control byte was [`Tag::DELETED`].
1940    ///
1941    /// See also [`Bucket::as_ptr`] method, for more information about of properly removing
1942    /// or saving `element` from / into the [`RawTable`] / [`RawTableInner`].
1943    ///
1944    /// [`Bucket::as_ptr`]: Bucket::as_ptr
1945    /// [`undefined behavior`]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
1946    /// [`RawTableInner::ctrl`]: RawTableInner::ctrl
1947    /// [`RawTableInner::set_ctrl_hash`]: RawTableInner::set_ctrl_hash
1948    /// [`RawTableInner::find_insert_index`]: RawTableInner::find_insert_index
1949    #[inline]
1950    unsafe fn prepare_insert_index(&mut self, hash: u64) -> (usize, Tag) {
1951        // SAFETY: Caller of this function ensures that the control bytes are properly initialized.
1952        let index: usize = self.find_insert_index(hash);
1953        // SAFETY:
1954        // 1. The `find_insert_index` function either returns an `index` less than or
1955        //    equal to `self.buckets() = self.bucket_mask + 1` of the table, or never
1956        //    returns if it cannot find an empty or deleted slot.
1957        // 2. The caller of this function guarantees that the table has already been
1958        //    allocated
1959        let old_ctrl = *self.ctrl(index);
1960        self.set_ctrl_hash(index, hash);
1961        (index, old_ctrl)
1962    }
1963
1964    /// Searches for an empty or deleted bucket which is suitable for inserting
1965    /// a new element, returning the `index` for the new [`Bucket`].
1966    ///
1967    /// This function does not make any changes to the `data` part of the table, or any
1968    /// changes to the `items` or `growth_left` field of the table.
1969    ///
1970    /// The table must have at least 1 empty or deleted `bucket`, otherwise this function
1971    /// will never return (will go into an infinite loop) for tables larger than the group
1972    /// width, or return an index outside of the table indices range if the table is less
1973    /// than the group width.
1974    ///
1975    /// If there is at least 1 empty or deleted `bucket` in the table, the function is
1976    /// guaranteed to return an index in the range `0..self.buckets()`, but in any case,
1977    /// it will contain an index in the range `0..=self.buckets()`.
1978    ///
1979    /// # Safety
1980    ///
1981    /// The [`RawTableInner`] must have properly initialized control bytes otherwise calling
1982    /// this function results in [`undefined behavior`].
1983    ///
1984    /// Attempt to write data at the index returned by this function when the table is
1985    /// less than the group width and if there was not at least one empty or deleted bucket in
1986    /// the table will cause immediate [`undefined behavior`]. This is because in this case the
1987    /// function will return `self.bucket_mask + 1` as an index due to the trailing [`Tag::EMPTY`]
1988    /// control bytes outside the table range.
1989    ///
1990    /// [`undefined behavior`]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
1991    #[inline]
1992    unsafe fn find_insert_index(&self, hash: u64) -> usize {
1993        let mut probe_seq = self.probe_seq(hash);
1994        loop {
1995            // SAFETY:
1996            // * Caller of this function ensures that the control bytes are properly initialized.
1997            //
1998            // * `ProbeSeq.pos` cannot be greater than `self.bucket_mask = self.buckets() - 1`
1999            //   of the table due to masking with `self.bucket_mask` and also because the number
2000            //   of buckets is a power of two (see `self.probe_seq` function).
2001            //
2002            // * Even if `ProbeSeq.pos` returns `position == self.bucket_mask`, it is safe to
2003            //   call `Group::load` due to the extended control bytes range, which is
2004            //  `self.bucket_mask + 1 + Group::WIDTH` (in fact, this means that the last control
2005            //   byte will never be read for the allocated table);
2006            //
2007            // * Also, even if `RawTableInner` is not already allocated, `ProbeSeq.pos` will
2008            //   always return "0" (zero), so Group::load will read unaligned `Group::static_empty()`
2009            //   bytes, which is safe (see RawTableInner::new).
2010            let group = unsafe { Group::load(self.ctrl(probe_seq.pos)) };
2011
2012            let index = self.find_insert_index_in_group(&group, &probe_seq);
2013            if likely(index.is_some()) {
2014                // SAFETY:
2015                // * Caller of this function ensures that the control bytes are properly initialized.
2016                //
2017                // * We use this function with the slot / index found by `self.find_insert_index_in_group`
2018                unsafe {
2019                    return self.fix_insert_index(index.unwrap_unchecked());
2020                }
2021            }
2022            probe_seq.move_next(self.bucket_mask);
2023        }
2024    }
2025
2026    /// Searches for an element in a table, returning the `index` of the found element.
2027    /// This uses dynamic dispatch to reduce the amount of code generated, but it is
2028    /// eliminated by LLVM optimizations.
2029    ///
2030    /// This function does not make any changes to the `data` part of the table, or any
2031    /// changes to the `items` or `growth_left` field of the table.
2032    ///
2033    /// The table must have at least 1 empty `bucket`, otherwise, if the
2034    /// `eq: &mut dyn FnMut(usize) -> bool` function does not return `true`,
2035    /// this function will also never return (will go into an infinite loop).
2036    ///
2037    /// This function is guaranteed to provide the `eq: &mut dyn FnMut(usize) -> bool`
2038    /// function with only `FULL` buckets' indices and return the `index` of the found
2039    /// element as `Some(index)`, so the index will always be in the range
2040    /// `0..self.buckets()`.
2041    ///
2042    /// # Safety
2043    ///
2044    /// The [`RawTableInner`] must have properly initialized control bytes otherwise calling
2045    /// this function results in [`undefined behavior`].
2046    ///
2047    /// [`undefined behavior`]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
2048    #[inline(always)]
2049    unsafe fn find_inner(&self, hash: u64, eq: &mut dyn FnMut(usize) -> bool) -> Option<usize> {
2050        let tag_hash = Tag::full(hash);
2051        let mut probe_seq = self.probe_seq(hash);
2052
2053        loop {
2054            // SAFETY:
2055            // * Caller of this function ensures that the control bytes are properly initialized.
2056            //
2057            // * `ProbeSeq.pos` cannot be greater than `self.bucket_mask = self.buckets() - 1`
2058            //   of the table due to masking with `self.bucket_mask`.
2059            //
2060            // * Even if `ProbeSeq.pos` returns `position == self.bucket_mask`, it is safe to
2061            //   call `Group::load` due to the extended control bytes range, which is
2062            //  `self.bucket_mask + 1 + Group::WIDTH` (in fact, this means that the last control
2063            //   byte will never be read for the allocated table);
2064            //
2065            // * Also, even if `RawTableInner` is not already allocated, `ProbeSeq.pos` will
2066            //   always return "0" (zero), so Group::load will read unaligned `Group::static_empty()`
2067            //   bytes, which is safe (see RawTableInner::new_in).
2068            let group = unsafe { Group::load(self.ctrl(probe_seq.pos)) };
2069
2070            for bit in group.match_tag(tag_hash) {
2071                // This is the same as `(probe_seq.pos + bit) % self.buckets()` because the number
2072                // of buckets is a power of two, and `self.bucket_mask = self.buckets() - 1`.
2073                let index = (probe_seq.pos + bit) & self.bucket_mask;
2074
2075                if likely(eq(index)) {
2076                    return Some(index);
2077                }
2078            }
2079
2080            if likely(group.match_empty().any_bit_set()) {
2081                return None;
2082            }
2083
2084            probe_seq.move_next(self.bucket_mask);
2085        }
2086    }
2087
2088    /// Prepares for rehashing data in place (that is, without allocating new memory).
2089    /// Converts all full index `control bytes` to `Tag::DELETED` and all `Tag::DELETED` control
2090    /// bytes to `Tag::EMPTY`, i.e. performs the following conversion:
2091    ///
2092    /// - `Tag::EMPTY` control bytes   -> `Tag::EMPTY`;
2093    /// - `Tag::DELETED` control bytes -> `Tag::EMPTY`;
2094    /// - `FULL` control bytes    -> `Tag::DELETED`.
2095    ///
2096    /// This function does not make any changes to the `data` parts of the table,
2097    /// or any changes to the `items` or `growth_left` field of the table.
2098    ///
2099    /// # Safety
2100    ///
2101    /// You must observe the following safety rules when calling this function:
2102    ///
2103    /// * The [`RawTableInner`] has already been allocated;
2104    ///
2105    /// * The caller of this function must convert the `Tag::DELETED` bytes back to `FULL`
2106    ///   bytes when re-inserting them into their ideal position (which was impossible
2107    ///   to do during the first insert due to tombstones). If the caller does not do
2108    ///   this, then calling this function may result in a memory leak.
2109    ///
2110    /// * The [`RawTableInner`] must have properly initialized control bytes otherwise
2111    ///   calling this function results in [`undefined behavior`].
2112    ///
2113    /// Calling this function on a table that has not been allocated results in
2114    /// [`undefined behavior`].
2115    ///
2116    /// See also [`Bucket::as_ptr`] method, for more information about of properly removing
2117    /// or saving `data element` from / into the [`RawTable`] / [`RawTableInner`].
2118    ///
2119    /// [`Bucket::as_ptr`]: Bucket::as_ptr
2120    /// [`undefined behavior`]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
2121    #[allow(clippy::mut_mut)]
2122    #[inline]
2123    unsafe fn prepare_rehash_in_place(&mut self) {
2124        // Bulk convert all full control bytes to DELETED, and all DELETED control bytes to EMPTY.
2125        // This effectively frees up all buckets containing a DELETED entry.
2126        //
2127        // SAFETY:
2128        // 1. `i` is guaranteed to be within bounds since we are iterating from zero to `buckets - 1`;
2129        // 2. Even if `i` will be `i == self.bucket_mask`, it is safe to call `Group::load_aligned`
2130        //    due to the extended control bytes range, which is `self.bucket_mask + 1 + Group::WIDTH`;
2131        // 3. The caller of this function guarantees that [`RawTableInner`] has already been allocated;
2132        // 4. We can use `Group::load_aligned` and `Group::store_aligned` here since we start from 0
2133        //    and go to the end with a step equal to `Group::WIDTH` (see TableLayout::calculate_layout_for).
2134        for i in (0..self.buckets()).step_by(Group::WIDTH) {
2135            let group = Group::load_aligned(self.ctrl(i));
2136            let group = group.convert_special_to_empty_and_full_to_deleted();
2137            group.store_aligned(self.ctrl(i));
2138        }
2139
2140        // Fix up the trailing control bytes. See the comments in set_ctrl
2141        // for the handling of tables smaller than the group width.
2142        //
2143        // SAFETY: The caller of this function guarantees that [`RawTableInner`]
2144        // has already been allocated
2145        if unlikely(self.buckets() < Group::WIDTH) {
2146            // SAFETY: We have `self.bucket_mask + 1 + Group::WIDTH` number of control bytes,
2147            // so copying `self.buckets() == self.bucket_mask + 1` bytes with offset equal to
2148            // `Group::WIDTH` is safe
2149            self.ctrl(0)
2150                .copy_to(self.ctrl(Group::WIDTH), self.buckets());
2151        } else {
2152            // SAFETY: We have `self.bucket_mask + 1 + Group::WIDTH` number of
2153            // control bytes,so copying `Group::WIDTH` bytes with offset equal
2154            // to `self.buckets() == self.bucket_mask + 1` is safe
2155            self.ctrl(0)
2156                .copy_to(self.ctrl(self.buckets()), Group::WIDTH);
2157        }
2158    }
2159
2160    /// Returns an iterator over every element in the table.
2161    ///
2162    /// # Safety
2163    ///
2164    /// If any of the following conditions are violated, the result
2165    /// is [`undefined behavior`]:
2166    ///
2167    /// * The caller has to ensure that the `RawTableInner` outlives the
2168    ///   `RawIter`. Because we cannot make the `next` method unsafe on
2169    ///   the `RawIter` struct, we have to make the `iter` method unsafe.
2170    ///
2171    /// * The [`RawTableInner`] must have properly initialized control bytes.
2172    ///
2173    /// The type `T` must be the actual type of the elements stored in the table,
2174    /// otherwise using the returned [`RawIter`] results in [`undefined behavior`].
2175    ///
2176    /// [`undefined behavior`]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
2177    #[inline]
2178    unsafe fn iter<T>(&self) -> RawIter<T> {
2179        // SAFETY:
2180        // 1. Since the caller of this function ensures that the control bytes
2181        //    are properly initialized and `self.data_end()` points to the start
2182        //    of the array of control bytes, therefore: `ctrl` is valid for reads,
2183        //    properly aligned to `Group::WIDTH` and points to the properly initialized
2184        //    control bytes.
2185        // 2. `data` bucket index in the table is equal to the `ctrl` index (i.e.
2186        //    equal to zero).
2187        // 3. We pass the exact value of buckets of the table to the function.
2188        //
2189        //                         `ctrl` points here (to the start
2190        //                         of the first control byte `CT0`)
2191        //                          ∨
2192        // [Pad], T_n, ..., T1, T0, |CT0, CT1, ..., CT_n|, CTa_0, CTa_1, ..., CTa_m
2193        //                           \________  ________/
2194        //                                    \/
2195        //       `n = buckets - 1`, i.e. `RawTableInner::buckets() - 1`
2196        //
2197        // where: T0...T_n  - our stored data;
2198        //        CT0...CT_n - control bytes or metadata for `data`.
2199        //        CTa_0...CTa_m - additional control bytes, where `m = Group::WIDTH - 1` (so that the search
2200        //                        with loading `Group` bytes from the heap works properly, even if the result
2201        //                        of `h1(hash) & self.bucket_mask` is equal to `self.bucket_mask`). See also
2202        //                        `RawTableInner::set_ctrl` function.
2203        //
2204        // P.S. `h1(hash) & self.bucket_mask` is the same as `hash as usize % self.buckets()` because the number
2205        // of buckets is a power of two, and `self.bucket_mask = self.buckets() - 1`.
2206        let data = Bucket::from_base_index(self.data_end(), 0);
2207        RawIter {
2208            // SAFETY: See explanation above
2209            iter: RawIterRange::new(self.ctrl.as_ptr(), data, self.buckets()),
2210            items: self.items,
2211        }
2212    }
2213
2214    /// Executes the destructors (if any) of the values stored in the table.
2215    ///
2216    /// # Note
2217    ///
2218    /// This function does not erase the control bytes of the table and does
2219    /// not make any changes to the `items` or `growth_left` fields of the
2220    /// table. If necessary, the caller of this function must manually set
2221    /// up these table fields, for example using the [`clear_no_drop`] function.
2222    ///
2223    /// Be careful during calling this function, because drop function of
2224    /// the elements can panic, and this can leave table in an inconsistent
2225    /// state.
2226    ///
2227    /// # Safety
2228    ///
2229    /// The type `T` must be the actual type of the elements stored in the table,
2230    /// otherwise calling this function may result in [`undefined behavior`].
2231    ///
2232    /// If `T` is a type that should be dropped and **the table is not empty**,
2233    /// calling this function more than once results in [`undefined behavior`].
2234    ///
2235    /// If `T` is not [`Copy`], attempting to use values stored in the table after
2236    /// calling this function may result in [`undefined behavior`].
2237    ///
2238    /// It is safe to call this function on a table that has not been allocated,
2239    /// on a table with uninitialized control bytes, and on a table with no actual
2240    /// data but with `Full` control bytes if `self.items == 0`.
2241    ///
2242    /// See also [`Bucket::drop`] / [`Bucket::as_ptr`] methods, for more information
2243    /// about of properly removing or saving `element` from / into the [`RawTable`] /
2244    /// [`RawTableInner`].
2245    ///
2246    /// [`Bucket::drop`]: Bucket::drop
2247    /// [`Bucket::as_ptr`]: Bucket::as_ptr
2248    /// [`clear_no_drop`]: RawTableInner::clear_no_drop
2249    /// [`undefined behavior`]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
2250    unsafe fn drop_elements<T>(&mut self) {
2251        // Check that `self.items != 0`. Protects against the possibility
2252        // of creating an iterator on an table with uninitialized control bytes.
2253        if T::NEEDS_DROP && self.items != 0 {
2254            // SAFETY: We know for sure that RawTableInner will outlive the
2255            // returned `RawIter` iterator, and the caller of this function
2256            // must uphold the safety contract for `drop_elements` method.
2257            for item in self.iter::<T>() {
2258                // SAFETY: The caller must uphold the safety contract for
2259                // `drop_elements` method.
2260                item.drop();
2261            }
2262        }
2263    }
2264
2265    /// Executes the destructors (if any) of the values stored in the table and than
2266    /// deallocates the table.
2267    ///
2268    /// # Note
2269    ///
2270    /// Calling this function automatically makes invalid (dangling) all instances of
2271    /// buckets ([`Bucket`]) and makes invalid (dangling) the `ctrl` field of the table.
2272    ///
2273    /// This function does not make any changes to the `bucket_mask`, `items` or `growth_left`
2274    /// fields of the table. If necessary, the caller of this function must manually set
2275    /// up these table fields.
2276    ///
2277    /// # Safety
2278    ///
2279    /// If any of the following conditions are violated, the result is [`undefined behavior`]:
2280    ///
2281    /// * Calling this function more than once;
2282    ///
2283    /// * The type `T` must be the actual type of the elements stored in the table.
2284    ///
2285    /// * The `alloc` must be the same [`Allocator`] as the `Allocator` that was used
2286    ///   to allocate this table.
2287    ///
2288    /// * The `table_layout` must be the same [`TableLayout`] as the `TableLayout` that
2289    ///   was used to allocate this table.
2290    ///
2291    /// The caller of this function should pay attention to the possibility of the
2292    /// elements' drop function panicking, because this:
2293    ///
2294    ///    * May leave the table in an inconsistent state;
2295    ///
2296    ///    * Memory is never deallocated, so a memory leak may occur.
2297    ///
2298    /// Attempt to use the `ctrl` field of the table (dereference) after calling this
2299    /// function results in [`undefined behavior`].
2300    ///
2301    /// It is safe to call this function on a table that has not been allocated,
2302    /// on a table with uninitialized control bytes, and on a table with no actual
2303    /// data but with `Full` control bytes if `self.items == 0`.
2304    ///
2305    /// See also [`RawTableInner::drop_elements`] or [`RawTableInner::free_buckets`]
2306    /// for more  information.
2307    ///
2308    /// [`RawTableInner::drop_elements`]: RawTableInner::drop_elements
2309    /// [`RawTableInner::free_buckets`]: RawTableInner::free_buckets
2310    /// [`undefined behavior`]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
2311    unsafe fn drop_inner_table<T, A: Allocator>(&mut self, alloc: &A, table_layout: TableLayout) {
2312        if !self.is_empty_singleton() {
2313            unsafe {
2314                // SAFETY: The caller must uphold the safety contract for `drop_inner_table` method.
2315                self.drop_elements::<T>();
2316                // SAFETY:
2317                // 1. We have checked that our table is allocated.
2318                // 2. The caller must uphold the safety contract for `drop_inner_table` method.
2319                self.free_buckets(alloc, table_layout);
2320            }
2321        }
2322    }
2323
2324    /// Returns a pointer to an element in the table (convenience for
2325    /// `Bucket::from_base_index(self.data_end::<T>(), index)`).
2326    ///
2327    /// The caller must ensure that the `RawTableInner` outlives the returned [`Bucket<T>`],
2328    /// otherwise using it may result in [`undefined behavior`].
2329    ///
2330    /// # Safety
2331    ///
2332    /// If `mem::size_of::<T>() != 0`, then the safety rules are directly derived from the
2333    /// safety rules of the [`Bucket::from_base_index`] function. Therefore, when calling
2334    /// this function, the following safety rules must be observed:
2335    ///
2336    /// * The table must already be allocated;
2337    ///
2338    /// * The `index` must not be greater than the number returned by the [`RawTableInner::buckets`]
2339    ///   function, i.e. `(index + 1) <= self.buckets()`.
2340    ///
2341    /// * The type `T` must be the actual type of the elements stored in the table, otherwise
2342    ///   using the returned [`Bucket`] may result in [`undefined behavior`].
2343    ///
2344    /// It is safe to call this function with index of zero (`index == 0`) on a table that has
2345    /// not been allocated, but using the returned [`Bucket`] results in [`undefined behavior`].
2346    ///
2347    /// If `mem::size_of::<T>() == 0`, then the only requirement is that the `index` must
2348    /// not be greater than the number returned by the [`RawTable::buckets`] function, i.e.
2349    /// `(index + 1) <= self.buckets()`.
2350    ///
2351    /// ```none
2352    /// If mem::size_of::<T>() != 0 then return a pointer to the `element` in the `data part` of the table
2353    /// (we start counting from "0", so that in the expression T[n], the "n" index actually one less than
2354    /// the "buckets" number of our `RawTableInner`, i.e. "n = RawTableInner::buckets() - 1"):
2355    ///
2356    ///           `table.bucket(3).as_ptr()` returns a pointer that points here in the `data`
2357    ///           part of the `RawTableInner`, i.e. to the start of T3 (see [`Bucket::as_ptr`])
2358    ///                  |
2359    ///                  |               `base = table.data_end::<T>()` points here
2360    ///                  |               (to the start of CT0 or to the end of T0)
2361    ///                  v                 v
2362    /// [Pad], T_n, ..., |T3|, T2, T1, T0, |CT0, CT1, CT2, CT3, ..., CT_n, CTa_0, CTa_1, ..., CTa_m
2363    ///                     ^                                              \__________  __________/
2364    ///        `table.bucket(3)` returns a pointer that points                        \/
2365    ///         here in the `data` part of the `RawTableInner`             additional control bytes
2366    ///         (to the end of T3)                                          `m = Group::WIDTH - 1`
2367    ///
2368    /// where: T0...T_n  - our stored data;
2369    ///        CT0...CT_n - control bytes or metadata for `data`;
2370    ///        CTa_0...CTa_m - additional control bytes (so that the search with loading `Group` bytes from
2371    ///                        the heap works properly, even if the result of `h1(hash) & self.bucket_mask`
2372    ///                        is equal to `self.bucket_mask`). See also `RawTableInner::set_ctrl` function.
2373    ///
2374    /// P.S. `h1(hash) & self.bucket_mask` is the same as `hash as usize % self.buckets()` because the number
2375    /// of buckets is a power of two, and `self.bucket_mask = self.buckets() - 1`.
2376    /// ```
2377    ///
2378    /// [`Bucket::from_base_index`]: Bucket::from_base_index
2379    /// [`RawTableInner::buckets`]: RawTableInner::buckets
2380    /// [`undefined behavior`]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
2381    #[inline]
2382    unsafe fn bucket<T>(&self, index: usize) -> Bucket<T> {
2383        debug_assert_ne!(self.bucket_mask, 0);
2384        debug_assert!(index < self.buckets());
2385        Bucket::from_base_index(self.data_end(), index)
2386    }
2387
2388    /// Returns a raw `*mut u8` pointer to the start of the `data` element in the table
2389    /// (convenience for `self.data_end::<u8>().as_ptr().sub((index + 1) * size_of)`).
2390    ///
2391    /// The caller must ensure that the `RawTableInner` outlives the returned `*mut u8`,
2392    /// otherwise using it may result in [`undefined behavior`].
2393    ///
2394    /// # Safety
2395    ///
2396    /// If any of the following conditions are violated, the result is [`undefined behavior`]:
2397    ///
2398    /// * The table must already be allocated;
2399    ///
2400    /// * The `index` must not be greater than the number returned by the [`RawTableInner::buckets`]
2401    ///   function, i.e. `(index + 1) <= self.buckets()`;
2402    ///
2403    /// * The `size_of` must be equal to the size of the elements stored in the table;
2404    ///
2405    /// ```none
2406    /// If mem::size_of::<T>() != 0 then return a pointer to the `element` in the `data part` of the table
2407    /// (we start counting from "0", so that in the expression T[n], the "n" index actually one less than
2408    /// the "buckets" number of our `RawTableInner`, i.e. "n = RawTableInner::buckets() - 1"):
2409    ///
2410    ///           `table.bucket_ptr(3, mem::size_of::<T>())` returns a pointer that points here in the
2411    ///           `data` part of the `RawTableInner`, i.e. to the start of T3
2412    ///                  |
2413    ///                  |               `base = table.data_end::<u8>()` points here
2414    ///                  |               (to the start of CT0 or to the end of T0)
2415    ///                  v                 v
2416    /// [Pad], T_n, ..., |T3|, T2, T1, T0, |CT0, CT1, CT2, CT3, ..., CT_n, CTa_0, CTa_1, ..., CTa_m
2417    ///                                                                    \__________  __________/
2418    ///                                                                               \/
2419    ///                                                                    additional control bytes
2420    ///                                                                     `m = Group::WIDTH - 1`
2421    ///
2422    /// where: T0...T_n  - our stored data;
2423    ///        CT0...CT_n - control bytes or metadata for `data`;
2424    ///        CTa_0...CTa_m - additional control bytes (so that the search with loading `Group` bytes from
2425    ///                        the heap works properly, even if the result of `h1(hash) & self.bucket_mask`
2426    ///                        is equal to `self.bucket_mask`). See also `RawTableInner::set_ctrl` function.
2427    ///
2428    /// P.S. `h1(hash) & self.bucket_mask` is the same as `hash as usize % self.buckets()` because the number
2429    /// of buckets is a power of two, and `self.bucket_mask = self.buckets() - 1`.
2430    /// ```
2431    ///
2432    /// [`RawTableInner::buckets`]: RawTableInner::buckets
2433    /// [`undefined behavior`]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
2434    #[inline]
2435    unsafe fn bucket_ptr(&self, index: usize, size_of: usize) -> *mut u8 {
2436        debug_assert_ne!(self.bucket_mask, 0);
2437        debug_assert!(index < self.buckets());
2438        let base: *mut u8 = self.data_end().as_ptr();
2439        base.sub((index + 1) * size_of)
2440    }
2441
2442    /// Returns pointer to one past last `data` element in the table as viewed from
2443    /// the start point of the allocation (convenience for `self.ctrl.cast()`).
2444    ///
2445    /// This function actually returns a pointer to the end of the `data element` at
2446    /// index "0" (zero).
2447    ///
2448    /// The caller must ensure that the `RawTableInner` outlives the returned [`NonNull<T>`],
2449    /// otherwise using it may result in [`undefined behavior`].
2450    ///
2451    /// # Note
2452    ///
2453    /// The type `T` must be the actual type of the elements stored in the table, otherwise
2454    /// using the returned [`NonNull<T>`] may result in [`undefined behavior`].
2455    ///
2456    /// ```none
2457    ///                        `table.data_end::<T>()` returns pointer that points here
2458    ///                        (to the end of `T0`)
2459    ///                          ∨
2460    /// [Pad], T_n, ..., T1, T0, |CT0, CT1, ..., CT_n|, CTa_0, CTa_1, ..., CTa_m
2461    ///                           \________  ________/
2462    ///                                    \/
2463    ///       `n = buckets - 1`, i.e. `RawTableInner::buckets() - 1`
2464    ///
2465    /// where: T0...T_n  - our stored data;
2466    ///        CT0...CT_n - control bytes or metadata for `data`.
2467    ///        CTa_0...CTa_m - additional control bytes, where `m = Group::WIDTH - 1` (so that the search
2468    ///                        with loading `Group` bytes from the heap works properly, even if the result
2469    ///                        of `h1(hash) & self.bucket_mask` is equal to `self.bucket_mask`). See also
2470    ///                        `RawTableInner::set_ctrl` function.
2471    ///
2472    /// P.S. `h1(hash) & self.bucket_mask` is the same as `hash as usize % self.buckets()` because the number
2473    /// of buckets is a power of two, and `self.bucket_mask = self.buckets() - 1`.
2474    /// ```
2475    ///
2476    /// [`undefined behavior`]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
2477    #[inline]
2478    fn data_end<T>(&self) -> NonNull<T> {
2479        self.ctrl.cast()
2480    }
2481
2482    /// Returns an iterator-like object for a probe sequence on the table.
2483    ///
2484    /// This iterator never terminates, but is guaranteed to visit each bucket
2485    /// group exactly once. The loop using `probe_seq` must terminate upon
2486    /// reaching a group containing an empty bucket.
2487    #[inline]
2488    fn probe_seq(&self, hash: u64) -> ProbeSeq {
2489        ProbeSeq {
2490            // This is the same as `hash as usize % self.buckets()` because the number
2491            // of buckets is a power of two, and `self.bucket_mask = self.buckets() - 1`.
2492            pos: h1(hash) & self.bucket_mask,
2493            stride: 0,
2494        }
2495    }
2496
2497    #[inline]
2498    unsafe fn record_item_insert_at(&mut self, index: usize, old_ctrl: Tag, new_ctrl: Tag) {
2499        self.growth_left -= usize::from(old_ctrl.special_is_empty());
2500        self.set_ctrl(index, new_ctrl);
2501        self.items += 1;
2502    }
2503
2504    #[inline]
2505    fn is_in_same_group(&self, i: usize, new_i: usize, hash: u64) -> bool {
2506        let probe_seq_pos = self.probe_seq(hash).pos;
2507        let probe_index =
2508            |pos: usize| (pos.wrapping_sub(probe_seq_pos) & self.bucket_mask) / Group::WIDTH;
2509        probe_index(i) == probe_index(new_i)
2510    }
2511
2512    /// Sets a control byte to the hash, and possibly also the replicated control byte at
2513    /// the end of the array.
2514    ///
2515    /// This function does not make any changes to the `data` parts of the table,
2516    /// or any changes to the `items` or `growth_left` field of the table.
2517    ///
2518    /// # Safety
2519    ///
2520    /// The safety rules are directly derived from the safety rules for [`RawTableInner::set_ctrl`]
2521    /// method. Thus, in order to uphold the safety contracts for the method, you must observe the
2522    /// following rules when calling this function:
2523    ///
2524    /// * The [`RawTableInner`] has already been allocated;
2525    ///
2526    /// * The `index` must not be greater than the `RawTableInner.bucket_mask`, i.e.
2527    ///   `index <= RawTableInner.bucket_mask` or, in other words, `(index + 1)` must
2528    ///   be no greater than the number returned by the function [`RawTableInner::buckets`].
2529    ///
2530    /// Calling this function on a table that has not been allocated results in [`undefined behavior`].
2531    ///
2532    /// See also [`Bucket::as_ptr`] method, for more information about of properly removing
2533    /// or saving `data element` from / into the [`RawTable`] / [`RawTableInner`].
2534    ///
2535    /// [`RawTableInner::set_ctrl`]: RawTableInner::set_ctrl
2536    /// [`RawTableInner::buckets`]: RawTableInner::buckets
2537    /// [`Bucket::as_ptr`]: Bucket::as_ptr
2538    /// [`undefined behavior`]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
2539    #[inline]
2540    unsafe fn set_ctrl_hash(&mut self, index: usize, hash: u64) {
2541        // SAFETY: The caller must uphold the safety rules for the [`RawTableInner::set_ctrl_hash`]
2542        self.set_ctrl(index, Tag::full(hash));
2543    }
2544
2545    /// Replaces the hash in the control byte at the given index with the provided one,
2546    /// and possibly also replicates the new control byte at the end of the array of control
2547    /// bytes, returning the old control byte.
2548    ///
2549    /// This function does not make any changes to the `data` parts of the table,
2550    /// or any changes to the `items` or `growth_left` field of the table.
2551    ///
2552    /// # Safety
2553    ///
2554    /// The safety rules are directly derived from the safety rules for [`RawTableInner::set_ctrl_hash`]
2555    /// and [`RawTableInner::ctrl`] methods. Thus, in order to uphold the safety contracts for both
2556    /// methods, you must observe the following rules when calling this function:
2557    ///
2558    /// * The [`RawTableInner`] has already been allocated;
2559    ///
2560    /// * The `index` must not be greater than the `RawTableInner.bucket_mask`, i.e.
2561    ///   `index <= RawTableInner.bucket_mask` or, in other words, `(index + 1)` must
2562    ///   be no greater than the number returned by the function [`RawTableInner::buckets`].
2563    ///
2564    /// Calling this function on a table that has not been allocated results in [`undefined behavior`].
2565    ///
2566    /// See also [`Bucket::as_ptr`] method, for more information about of properly removing
2567    /// or saving `data element` from / into the [`RawTable`] / [`RawTableInner`].
2568    ///
2569    /// [`RawTableInner::set_ctrl_hash`]: RawTableInner::set_ctrl_hash
2570    /// [`RawTableInner::buckets`]: RawTableInner::buckets
2571    /// [`Bucket::as_ptr`]: Bucket::as_ptr
2572    /// [`undefined behavior`]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
2573    #[inline]
2574    unsafe fn replace_ctrl_hash(&mut self, index: usize, hash: u64) -> Tag {
2575        // SAFETY: The caller must uphold the safety rules for the [`RawTableInner::replace_ctrl_hash`]
2576        let prev_ctrl = *self.ctrl(index);
2577        self.set_ctrl_hash(index, hash);
2578        prev_ctrl
2579    }
2580
2581    /// Sets a control byte, and possibly also the replicated control byte at
2582    /// the end of the array.
2583    ///
2584    /// This function does not make any changes to the `data` parts of the table,
2585    /// or any changes to the `items` or `growth_left` field of the table.
2586    ///
2587    /// # Safety
2588    ///
2589    /// You must observe the following safety rules when calling this function:
2590    ///
2591    /// * The [`RawTableInner`] has already been allocated;
2592    ///
2593    /// * The `index` must not be greater than the `RawTableInner.bucket_mask`, i.e.
2594    ///   `index <= RawTableInner.bucket_mask` or, in other words, `(index + 1)` must
2595    ///   be no greater than the number returned by the function [`RawTableInner::buckets`].
2596    ///
2597    /// Calling this function on a table that has not been allocated results in [`undefined behavior`].
2598    ///
2599    /// See also [`Bucket::as_ptr`] method, for more information about of properly removing
2600    /// or saving `data element` from / into the [`RawTable`] / [`RawTableInner`].
2601    ///
2602    /// [`RawTableInner::buckets`]: RawTableInner::buckets
2603    /// [`Bucket::as_ptr`]: Bucket::as_ptr
2604    /// [`undefined behavior`]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
2605    #[inline]
2606    unsafe fn set_ctrl(&mut self, index: usize, ctrl: Tag) {
2607        // Replicate the first Group::WIDTH control bytes at the end of
2608        // the array without using a branch. If the tables smaller than
2609        // the group width (self.buckets() < Group::WIDTH),
2610        // `index2 = Group::WIDTH + index`, otherwise `index2` is:
2611        //
2612        // - If index >= Group::WIDTH then index == index2.
2613        // - Otherwise index2 == self.bucket_mask + 1 + index.
2614        //
2615        // The very last replicated control byte is never actually read because
2616        // we mask the initial index for unaligned loads, but we write it
2617        // anyways because it makes the set_ctrl implementation simpler.
2618        //
2619        // If there are fewer buckets than Group::WIDTH then this code will
2620        // replicate the buckets at the end of the trailing group. For example
2621        // with 2 buckets and a group size of 4, the control bytes will look
2622        // like this:
2623        //
2624        //     Real    |             Replicated
2625        // ---------------------------------------------
2626        // | [A] | [B] | [Tag::EMPTY] | [EMPTY] | [A] | [B] |
2627        // ---------------------------------------------
2628
2629        // This is the same as `(index.wrapping_sub(Group::WIDTH)) % self.buckets() + Group::WIDTH`
2630        // because the number of buckets is a power of two, and `self.bucket_mask = self.buckets() - 1`.
2631        let index2 = ((index.wrapping_sub(Group::WIDTH)) & self.bucket_mask) + Group::WIDTH;
2632
2633        // SAFETY: The caller must uphold the safety rules for the [`RawTableInner::set_ctrl`]
2634        *self.ctrl(index) = ctrl;
2635        *self.ctrl(index2) = ctrl;
2636    }
2637
2638    /// Returns a pointer to a control byte.
2639    ///
2640    /// # Safety
2641    ///
2642    /// For the allocated [`RawTableInner`], the result is [`Undefined Behavior`],
2643    /// if the `index` is greater than the `self.bucket_mask + 1 + Group::WIDTH`.
2644    /// In that case, calling this function with `index == self.bucket_mask + 1 + Group::WIDTH`
2645    /// will return a pointer to the end of the allocated table and it is useless on its own.
2646    ///
2647    /// Calling this function with `index >= self.bucket_mask + 1 + Group::WIDTH` on a
2648    /// table that has not been allocated results in [`Undefined Behavior`].
2649    ///
2650    /// So to satisfy both requirements you should always follow the rule that
2651    /// `index < self.bucket_mask + 1 + Group::WIDTH`
2652    ///
2653    /// Calling this function on [`RawTableInner`] that are not already allocated is safe
2654    /// for read-only purpose.
2655    ///
2656    /// See also [`Bucket::as_ptr()`] method, for more information about of properly removing
2657    /// or saving `data element` from / into the [`RawTable`] / [`RawTableInner`].
2658    ///
2659    /// [`Bucket::as_ptr()`]: Bucket::as_ptr()
2660    /// [`Undefined Behavior`]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
2661    #[inline]
2662    unsafe fn ctrl(&self, index: usize) -> *mut Tag {
2663        debug_assert!(index < self.num_ctrl_bytes());
2664        // SAFETY: The caller must uphold the safety rules for the [`RawTableInner::ctrl`]
2665        self.ctrl.as_ptr().add(index).cast()
2666    }
2667
2668    /// Gets the slice of all control bytes.
2669    fn ctrl_slice(&mut self) -> &mut [Tag] {
2670        // SAFETY: We've initialized all control bytes, and have the correct number.
2671        unsafe { slice::from_raw_parts_mut(self.ctrl.as_ptr().cast(), self.num_ctrl_bytes()) }
2672    }
2673
2674    #[inline]
2675    fn buckets(&self) -> usize {
2676        self.bucket_mask + 1
2677    }
2678
2679    /// Checks whether the bucket at `index` is full.
2680    ///
2681    /// # Safety
2682    ///
2683    /// The caller must ensure `index` is less than the number of buckets.
2684    #[inline]
2685    unsafe fn is_bucket_full(&self, index: usize) -> bool {
2686        debug_assert!(index < self.buckets());
2687        (*self.ctrl(index)).is_full()
2688    }
2689
2690    #[inline]
2691    fn num_ctrl_bytes(&self) -> usize {
2692        self.bucket_mask + 1 + Group::WIDTH
2693    }
2694
2695    #[inline]
2696    fn is_empty_singleton(&self) -> bool {
2697        self.bucket_mask == 0
2698    }
2699
2700    /// Attempts to allocate a new hash table with at least enough capacity
2701    /// for inserting the given number of elements without reallocating,
2702    /// and return it inside `ScopeGuard` to protect against panic in the hash
2703    /// function.
2704    ///
2705    /// # Note
2706    ///
2707    /// It is recommended (but not required):
2708    ///
2709    /// * That the new table's `capacity` be greater than or equal to `self.items`.
2710    ///
2711    /// * The `alloc` is the same [`Allocator`] as the `Allocator` used
2712    ///   to allocate this table.
2713    ///
2714    /// * The `table_layout` is the same [`TableLayout`] as the `TableLayout` used
2715    ///   to allocate this table.
2716    ///
2717    /// If `table_layout` does not match the `TableLayout` that was used to allocate
2718    /// this table, then using `mem::swap` with the `self` and the new table returned
2719    /// by this function results in [`undefined behavior`].
2720    ///
2721    /// [`undefined behavior`]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
2722    #[allow(clippy::mut_mut)]
2723    #[inline]
2724    fn prepare_resize<'a, A>(
2725        &self,
2726        alloc: &'a A,
2727        table_layout: TableLayout,
2728        capacity: usize,
2729        fallibility: Fallibility,
2730    ) -> Result<crate::scopeguard::ScopeGuard<Self, impl FnMut(&mut Self) + 'a>, TryReserveError>
2731    where
2732        A: Allocator,
2733    {
2734        debug_assert!(self.items <= capacity);
2735
2736        // Allocate and initialize the new table.
2737        let new_table =
2738            RawTableInner::fallible_with_capacity(alloc, table_layout, capacity, fallibility)?;
2739
2740        // The hash function may panic, in which case we simply free the new
2741        // table without dropping any elements that may have been copied into
2742        // it.
2743        //
2744        // This guard is also used to free the old table on success, see
2745        // the comment at the bottom of this function.
2746        Ok(guard(new_table, move |self_| {
2747            if !self_.is_empty_singleton() {
2748                // SAFETY:
2749                // 1. We have checked that our table is allocated.
2750                // 2. We know for sure that the `alloc` and `table_layout` matches the
2751                //    [`Allocator`] and [`TableLayout`] used to allocate this table.
2752                unsafe { self_.free_buckets(alloc, table_layout) };
2753            }
2754        }))
2755    }
2756
2757    /// Reserves or rehashes to make room for `additional` more elements.
2758    ///
2759    /// This uses dynamic dispatch to reduce the amount of
2760    /// code generated, but it is eliminated by LLVM optimizations when inlined.
2761    ///
2762    /// # Safety
2763    ///
2764    /// If any of the following conditions are violated, the result is
2765    /// [`undefined behavior`]:
2766    ///
2767    /// * The `alloc` must be the same [`Allocator`] as the `Allocator` used
2768    ///   to allocate this table.
2769    ///
2770    /// * The `layout` must be the same [`TableLayout`] as the `TableLayout`
2771    ///   used to allocate this table.
2772    ///
2773    /// * The `drop` function (`fn(*mut u8)`) must be the actual drop function of
2774    ///   the elements stored in the table.
2775    ///
2776    /// * The [`RawTableInner`] must have properly initialized control bytes.
2777    ///
2778    /// [`undefined behavior`]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
2779    #[allow(clippy::inline_always)]
2780    #[inline(always)]
2781    unsafe fn reserve_rehash_inner<A>(
2782        &mut self,
2783        alloc: &A,
2784        additional: usize,
2785        hasher: &dyn Fn(&mut Self, usize) -> u64,
2786        fallibility: Fallibility,
2787        layout: TableLayout,
2788        drop: Option<unsafe fn(*mut u8)>,
2789    ) -> Result<(), TryReserveError>
2790    where
2791        A: Allocator,
2792    {
2793        // Avoid `Option::ok_or_else` because it bloats LLVM IR.
2794        let new_items = match self.items.checked_add(additional) {
2795            Some(new_items) => new_items,
2796            None => return Err(fallibility.capacity_overflow()),
2797        };
2798        let full_capacity = bucket_mask_to_capacity(self.bucket_mask);
2799        if new_items <= full_capacity / 2 {
2800            // Rehash in-place without re-allocating if we have plenty of spare
2801            // capacity that is locked up due to DELETED entries.
2802
2803            // SAFETY:
2804            // 1. We know for sure that `[`RawTableInner`]` has already been allocated
2805            //    (since new_items <= full_capacity / 2);
2806            // 2. The caller ensures that `drop` function is the actual drop function of
2807            //    the elements stored in the table.
2808            // 3. The caller ensures that `layout` matches the [`TableLayout`] that was
2809            //    used to allocate this table.
2810            // 4. The caller ensures that the control bytes of the `RawTableInner`
2811            //    are already initialized.
2812            self.rehash_in_place(hasher, layout.size, drop);
2813            Ok(())
2814        } else {
2815            // Otherwise, conservatively resize to at least the next size up
2816            // to avoid churning deletes into frequent rehashes.
2817            //
2818            // SAFETY:
2819            // 1. We know for sure that `capacity >= self.items`.
2820            // 2. The caller ensures that `alloc` and `layout` matches the [`Allocator`] and
2821            //    [`TableLayout`] that were used to allocate this table.
2822            // 3. The caller ensures that the control bytes of the `RawTableInner`
2823            //    are already initialized.
2824            self.resize_inner(
2825                alloc,
2826                usize::max(new_items, full_capacity + 1),
2827                hasher,
2828                fallibility,
2829                layout,
2830            )
2831        }
2832    }
2833
2834    /// Returns an iterator over full buckets indices in the table.
2835    ///
2836    /// # Safety
2837    ///
2838    /// Behavior is undefined if any of the following conditions are violated:
2839    ///
2840    /// * The caller has to ensure that the `RawTableInner` outlives the
2841    ///   `FullBucketsIndices`. Because we cannot make the `next` method
2842    ///   unsafe on the `FullBucketsIndices` struct, we have to make the
2843    ///   `full_buckets_indices` method unsafe.
2844    ///
2845    /// * The [`RawTableInner`] must have properly initialized control bytes.
2846    #[inline(always)]
2847    unsafe fn full_buckets_indices(&self) -> FullBucketsIndices {
2848        // SAFETY:
2849        // 1. Since the caller of this function ensures that the control bytes
2850        //    are properly initialized and `self.ctrl(0)` points to the start
2851        //    of the array of control bytes, therefore: `ctrl` is valid for reads,
2852        //    properly aligned to `Group::WIDTH` and points to the properly initialized
2853        //    control bytes.
2854        // 2. The value of `items` is equal to the amount of data (values) added
2855        //    to the table.
2856        //
2857        //                         `ctrl` points here (to the start
2858        //                         of the first control byte `CT0`)
2859        //                          ∨
2860        // [Pad], T_n, ..., T1, T0, |CT0, CT1, ..., CT_n|, Group::WIDTH
2861        //                           \________  ________/
2862        //                                    \/
2863        //       `n = buckets - 1`, i.e. `RawTableInner::buckets() - 1`
2864        //
2865        // where: T0...T_n  - our stored data;
2866        //        CT0...CT_n - control bytes or metadata for `data`.
2867        let ctrl = NonNull::new_unchecked(self.ctrl(0).cast::<u8>());
2868
2869        FullBucketsIndices {
2870            // Load the first group
2871            // SAFETY: See explanation above.
2872            current_group: Group::load_aligned(ctrl.as_ptr().cast())
2873                .match_full()
2874                .into_iter(),
2875            group_first_index: 0,
2876            ctrl,
2877            items: self.items,
2878        }
2879    }
2880
2881    /// Allocates a new table of a different size and moves the contents of the
2882    /// current table into it.
2883    ///
2884    /// This uses dynamic dispatch to reduce the amount of
2885    /// code generated, but it is eliminated by LLVM optimizations when inlined.
2886    ///
2887    /// # Safety
2888    ///
2889    /// If any of the following conditions are violated, the result is
2890    /// [`undefined behavior`]:
2891    ///
2892    /// * The `alloc` must be the same [`Allocator`] as the `Allocator` used
2893    ///   to allocate this table;
2894    ///
2895    /// * The `layout` must be the same [`TableLayout`] as the `TableLayout`
2896    ///   used to allocate this table;
2897    ///
2898    /// * The [`RawTableInner`] must have properly initialized control bytes.
2899    ///
2900    /// The caller of this function must ensure that `capacity >= self.items`
2901    /// otherwise:
2902    ///
2903    /// * If `self.items != 0`, calling of this function with `capacity == 0`
2904    ///   results in [`undefined behavior`].
2905    ///
2906    /// * If `capacity_to_buckets(capacity) < Group::WIDTH` and
2907    ///   `self.items > capacity_to_buckets(capacity)` calling this function
2908    ///   results in [`undefined behavior`].
2909    ///
2910    /// * If `capacity_to_buckets(capacity) >= Group::WIDTH` and
2911    ///   `self.items > capacity_to_buckets(capacity)` calling this function
2912    ///   are never return (will go into an infinite loop).
2913    ///
2914    /// Note: It is recommended (but not required) that the new table's `capacity`
2915    /// be greater than or equal to `self.items`. In case if `capacity <= self.items`
2916    /// this function can never return. See [`RawTableInner::find_insert_index`] for
2917    /// more information.
2918    ///
2919    /// [`RawTableInner::find_insert_index`]: RawTableInner::find_insert_index
2920    /// [`undefined behavior`]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
2921    #[allow(clippy::inline_always)]
2922    #[inline(always)]
2923    unsafe fn resize_inner<A>(
2924        &mut self,
2925        alloc: &A,
2926        capacity: usize,
2927        hasher: &dyn Fn(&mut Self, usize) -> u64,
2928        fallibility: Fallibility,
2929        layout: TableLayout,
2930    ) -> Result<(), TryReserveError>
2931    where
2932        A: Allocator,
2933    {
2934        // SAFETY: We know for sure that `alloc` and `layout` matches the [`Allocator`] and [`TableLayout`]
2935        // that were used to allocate this table.
2936        let mut new_table = self.prepare_resize(alloc, layout, capacity, fallibility)?;
2937
2938        // SAFETY: We know for sure that RawTableInner will outlive the
2939        // returned `FullBucketsIndices` iterator, and the caller of this
2940        // function ensures that the control bytes are properly initialized.
2941        for full_byte_index in self.full_buckets_indices() {
2942            // This may panic.
2943            let hash = hasher(self, full_byte_index);
2944
2945            // SAFETY:
2946            // We can use a simpler version of insert() here since:
2947            // 1. There are no DELETED entries.
2948            // 2. We know there is enough space in the table.
2949            // 3. All elements are unique.
2950            // 4. The caller of this function guarantees that `capacity > 0`
2951            //    so `new_table` must already have some allocated memory.
2952            // 5. We set `growth_left` and `items` fields of the new table
2953            //    after the loop.
2954            // 6. We insert into the table, at the returned index, the data
2955            //    matching the given hash immediately after calling this function.
2956            let (new_index, _) = new_table.prepare_insert_index(hash);
2957
2958            // SAFETY:
2959            //
2960            // * `src` is valid for reads of `layout.size` bytes, since the
2961            //   table is alive and the `full_byte_index` is guaranteed to be
2962            //   within bounds (see `FullBucketsIndices::next_impl`);
2963            //
2964            // * `dst` is valid for writes of `layout.size` bytes, since the
2965            //   caller ensures that `table_layout` matches the [`TableLayout`]
2966            //   that was used to allocate old table and we have the `new_index`
2967            //   returned by `prepare_insert_index`.
2968            //
2969            // * Both `src` and `dst` are properly aligned.
2970            //
2971            // * Both `src` and `dst` point to different region of memory.
2972            ptr::copy_nonoverlapping(
2973                self.bucket_ptr(full_byte_index, layout.size),
2974                new_table.bucket_ptr(new_index, layout.size),
2975                layout.size,
2976            );
2977        }
2978
2979        // The hash function didn't panic, so we can safely set the
2980        // `growth_left` and `items` fields of the new table.
2981        new_table.growth_left -= self.items;
2982        new_table.items = self.items;
2983
2984        // We successfully copied all elements without panicking. Now replace
2985        // self with the new table. The old table will have its memory freed but
2986        // the items will not be dropped (since they have been moved into the
2987        // new table).
2988        // SAFETY: The caller ensures that `table_layout` matches the [`TableLayout`]
2989        // that was used to allocate this table.
2990        mem::swap(self, &mut new_table);
2991
2992        Ok(())
2993    }
2994
2995    /// Rehashes the contents of the table in place (i.e. without changing the
2996    /// allocation).
2997    ///
2998    /// If `hasher` panics then some the table's contents may be lost.
2999    ///
3000    /// This uses dynamic dispatch to reduce the amount of
3001    /// code generated, but it is eliminated by LLVM optimizations when inlined.
3002    ///
3003    /// # Safety
3004    ///
3005    /// If any of the following conditions are violated, the result is [`undefined behavior`]:
3006    ///
3007    /// * The `size_of` must be equal to the size of the elements stored in the table;
3008    ///
3009    /// * The `drop` function (`fn(*mut u8)`) must be the actual drop function of
3010    ///   the elements stored in the table.
3011    ///
3012    /// * The [`RawTableInner`] has already been allocated;
3013    ///
3014    /// * The [`RawTableInner`] must have properly initialized control bytes.
3015    ///
3016    /// [`undefined behavior`]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
3017    #[allow(clippy::inline_always)]
3018    #[cfg_attr(feature = "inline-more", inline(always))]
3019    #[cfg_attr(not(feature = "inline-more"), inline)]
3020    unsafe fn rehash_in_place(
3021        &mut self,
3022        hasher: &dyn Fn(&mut Self, usize) -> u64,
3023        size_of: usize,
3024        drop: Option<unsafe fn(*mut u8)>,
3025    ) {
3026        // If the hash function panics then properly clean up any elements
3027        // that we haven't rehashed yet. We unfortunately can't preserve the
3028        // element since we lost their hash and have no way of recovering it
3029        // without risking another panic.
3030        self.prepare_rehash_in_place();
3031
3032        let mut guard = guard(self, move |self_| {
3033            if let Some(drop) = drop {
3034                for i in 0..self_.buckets() {
3035                    if *self_.ctrl(i) == Tag::DELETED {
3036                        self_.set_ctrl(i, Tag::EMPTY);
3037                        drop(self_.bucket_ptr(i, size_of));
3038                        self_.items -= 1;
3039                    }
3040                }
3041            }
3042            self_.growth_left = bucket_mask_to_capacity(self_.bucket_mask) - self_.items;
3043        });
3044
3045        // At this point, DELETED elements are elements that we haven't
3046        // rehashed yet. Find them and re-insert them at their ideal
3047        // position.
3048        'outer: for i in 0..guard.buckets() {
3049            if *guard.ctrl(i) != Tag::DELETED {
3050                continue;
3051            }
3052
3053            let i_p = guard.bucket_ptr(i, size_of);
3054
3055            'inner: loop {
3056                // Hash the current item
3057                let hash = hasher(*guard, i);
3058
3059                // Search for a suitable place to put it
3060                //
3061                // SAFETY: Caller of this function ensures that the control bytes
3062                // are properly initialized.
3063                let new_i = guard.find_insert_index(hash);
3064
3065                // Probing works by scanning through all of the control
3066                // bytes in groups, which may not be aligned to the group
3067                // size. If both the new and old position fall within the
3068                // same unaligned group, then there is no benefit in moving
3069                // it and we can just continue to the next item.
3070                if likely(guard.is_in_same_group(i, new_i, hash)) {
3071                    guard.set_ctrl_hash(i, hash);
3072                    continue 'outer;
3073                }
3074
3075                let new_i_p = guard.bucket_ptr(new_i, size_of);
3076
3077                // We are moving the current item to a new position. Write
3078                // our H2 to the control byte of the new position.
3079                let prev_ctrl = guard.replace_ctrl_hash(new_i, hash);
3080                if prev_ctrl == Tag::EMPTY {
3081                    guard.set_ctrl(i, Tag::EMPTY);
3082                    // If the target slot is empty, simply move the current
3083                    // element into the new slot and clear the old control
3084                    // byte.
3085                    ptr::copy_nonoverlapping(i_p, new_i_p, size_of);
3086                    continue 'outer;
3087                } else {
3088                    // If the target slot is occupied, swap the two elements
3089                    // and then continue processing the element that we just
3090                    // swapped into the old slot.
3091                    debug_assert_eq!(prev_ctrl, Tag::DELETED);
3092                    ptr::swap_nonoverlapping(i_p, new_i_p, size_of);
3093                    continue 'inner;
3094                }
3095            }
3096        }
3097
3098        guard.growth_left = bucket_mask_to_capacity(guard.bucket_mask) - guard.items;
3099
3100        mem::forget(guard);
3101    }
3102
3103    /// Deallocates the table without dropping any entries.
3104    ///
3105    /// # Note
3106    ///
3107    /// This function must be called only after [`drop_elements`](RawTableInner::drop_elements),
3108    /// else it can lead to leaking of memory. Also calling this function automatically
3109    /// makes invalid (dangling) all instances of buckets ([`Bucket`]) and makes invalid
3110    /// (dangling) the `ctrl` field of the table.
3111    ///
3112    /// # Safety
3113    ///
3114    /// If any of the following conditions are violated, the result is [`Undefined Behavior`]:
3115    ///
3116    /// * The [`RawTableInner`] has already been allocated;
3117    ///
3118    /// * The `alloc` must be the same [`Allocator`] as the `Allocator` that was used
3119    ///   to allocate this table.
3120    ///
3121    /// * The `table_layout` must be the same [`TableLayout`] as the `TableLayout` that was used
3122    ///   to allocate this table.
3123    ///
3124    /// See also [`GlobalAlloc::dealloc`] or [`Allocator::deallocate`] for more  information.
3125    ///
3126    /// [`Undefined Behavior`]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
3127    /// [`GlobalAlloc::dealloc`]: https://doc.rust-lang.org/alloc/alloc/trait.GlobalAlloc.html#tymethod.dealloc
3128    /// [`Allocator::deallocate`]: https://doc.rust-lang.org/alloc/alloc/trait.Allocator.html#tymethod.deallocate
3129    #[inline]
3130    unsafe fn free_buckets<A>(&mut self, alloc: &A, table_layout: TableLayout)
3131    where
3132        A: Allocator,
3133    {
3134        // SAFETY: The caller must uphold the safety contract for `free_buckets`
3135        // method.
3136        let (ptr, layout) = self.allocation_info(table_layout);
3137        alloc.deallocate(ptr, layout);
3138    }
3139
3140    /// Returns a pointer to the allocated memory and the layout that was used to
3141    /// allocate the table.
3142    ///
3143    /// # Safety
3144    ///
3145    /// Caller of this function must observe the following safety rules:
3146    ///
3147    /// * The [`RawTableInner`] has already been allocated, otherwise
3148    ///   calling this function results in [`undefined behavior`]
3149    ///
3150    /// * The `table_layout` must be the same [`TableLayout`] as the `TableLayout`
3151    ///   that was used to allocate this table. Failure to comply with this condition
3152    ///   may result in [`undefined behavior`].
3153    ///
3154    /// See also [`GlobalAlloc::dealloc`] or [`Allocator::deallocate`] for more  information.
3155    ///
3156    /// [`undefined behavior`]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
3157    /// [`GlobalAlloc::dealloc`]: https://doc.rust-lang.org/alloc/alloc/trait.GlobalAlloc.html#tymethod.dealloc
3158    /// [`Allocator::deallocate`]: https://doc.rust-lang.org/alloc/alloc/trait.Allocator.html#tymethod.deallocate
3159    #[inline]
3160    unsafe fn allocation_info(&self, table_layout: TableLayout) -> (NonNull<u8>, Layout) {
3161        debug_assert!(
3162            !self.is_empty_singleton(),
3163            "this function can only be called on non-empty tables"
3164        );
3165
3166        // Avoid `Option::unwrap_or_else` because it bloats LLVM IR.
3167        let (layout, ctrl_offset) = match table_layout.calculate_layout_for(self.buckets()) {
3168            Some(lco) => lco,
3169            None => unsafe { hint::unreachable_unchecked() },
3170        };
3171        (
3172            // SAFETY: The caller must uphold the safety contract for `allocation_info` method.
3173            unsafe { NonNull::new_unchecked(self.ctrl.as_ptr().sub(ctrl_offset)) },
3174            layout,
3175        )
3176    }
3177
3178    /// Returns the total amount of memory allocated internally by the hash
3179    /// table, in bytes.
3180    ///
3181    /// The returned number is informational only. It is intended to be
3182    /// primarily used for memory profiling.
3183    ///
3184    /// # Safety
3185    ///
3186    /// The `table_layout` must be the same [`TableLayout`] as the `TableLayout`
3187    /// that was used to allocate this table. Failure to comply with this condition
3188    /// may result in [`undefined behavior`].
3189    ///
3190    ///
3191    /// [`undefined behavior`]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
3192    #[inline]
3193    unsafe fn allocation_size_or_zero(&self, table_layout: TableLayout) -> usize {
3194        if self.is_empty_singleton() {
3195            0
3196        } else {
3197            // SAFETY:
3198            // 1. We have checked that our table is allocated.
3199            // 2. The caller ensures that `table_layout` matches the [`TableLayout`]
3200            // that was used to allocate this table.
3201            unsafe { self.allocation_info(table_layout).1.size() }
3202        }
3203    }
3204
3205    /// Marks all table buckets as empty without dropping their contents.
3206    #[inline]
3207    fn clear_no_drop(&mut self) {
3208        if !self.is_empty_singleton() {
3209            self.ctrl_slice().fill_empty();
3210        }
3211        self.items = 0;
3212        self.growth_left = bucket_mask_to_capacity(self.bucket_mask);
3213    }
3214
3215    /// Erases the [`Bucket`]'s control byte at the given index so that it does not
3216    /// triggered as full, decreases the `items` of the table and, if it can be done,
3217    /// increases `self.growth_left`.
3218    ///
3219    /// This function does not actually erase / drop the [`Bucket`] itself, i.e. it
3220    /// does not make any changes to the `data` parts of the table. The caller of this
3221    /// function must take care to properly drop the `data`, otherwise calling this
3222    /// function may result in a memory leak.
3223    ///
3224    /// # Safety
3225    ///
3226    /// You must observe the following safety rules when calling this function:
3227    ///
3228    /// * The [`RawTableInner`] has already been allocated;
3229    ///
3230    /// * It must be the full control byte at the given position;
3231    ///
3232    /// * The `index` must not be greater than the `RawTableInner.bucket_mask`, i.e.
3233    ///   `index <= RawTableInner.bucket_mask` or, in other words, `(index + 1)` must
3234    ///   be no greater than the number returned by the function [`RawTableInner::buckets`].
3235    ///
3236    /// Calling this function on a table that has not been allocated results in [`undefined behavior`].
3237    ///
3238    /// Calling this function on a table with no elements is unspecified, but calling subsequent
3239    /// functions is likely to result in [`undefined behavior`] due to overflow subtraction
3240    /// (`self.items -= 1 cause overflow when self.items == 0`).
3241    ///
3242    /// See also [`Bucket::as_ptr`] method, for more information about of properly removing
3243    /// or saving `data element` from / into the [`RawTable`] / [`RawTableInner`].
3244    ///
3245    /// [`RawTableInner::buckets`]: RawTableInner::buckets
3246    /// [`Bucket::as_ptr`]: Bucket::as_ptr
3247    /// [`undefined behavior`]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
3248    #[inline]
3249    unsafe fn erase(&mut self, index: usize) {
3250        debug_assert!(self.is_bucket_full(index));
3251
3252        // This is the same as `index.wrapping_sub(Group::WIDTH) % self.buckets()` because
3253        // the number of buckets is a power of two, and `self.bucket_mask = self.buckets() - 1`.
3254        let index_before = index.wrapping_sub(Group::WIDTH) & self.bucket_mask;
3255        // SAFETY:
3256        // - The caller must uphold the safety contract for `erase` method;
3257        // - `index_before` is guaranteed to be in range due to masking with `self.bucket_mask`
3258        let empty_before = Group::load(self.ctrl(index_before)).match_empty();
3259        let empty_after = Group::load(self.ctrl(index)).match_empty();
3260
3261        // Inserting and searching in the map is performed by two key functions:
3262        //
3263        // - The `find_insert_index` function that looks up the index of any `Tag::EMPTY` or `Tag::DELETED`
3264        //   slot in a group to be able to insert. If it doesn't find an `Tag::EMPTY` or `Tag::DELETED`
3265        //   slot immediately in the first group, it jumps to the next `Group` looking for it,
3266        //   and so on until it has gone through all the groups in the control bytes.
3267        //
3268        // - The `find_inner` function that looks for the index of the desired element by looking
3269        //   at all the `FULL` bytes in the group. If it did not find the element right away, and
3270        //   there is no `Tag::EMPTY` byte in the group, then this means that the `find_insert_index`
3271        //   function may have found a suitable slot in the next group. Therefore, `find_inner`
3272        //   jumps further, and if it does not find the desired element and again there is no `Tag::EMPTY`
3273        //   byte, then it jumps further, and so on. The search stops only if `find_inner` function
3274        //   finds the desired element or hits an `Tag::EMPTY` slot/byte.
3275        //
3276        // Accordingly, this leads to two consequences:
3277        //
3278        // - The map must have `Tag::EMPTY` slots (bytes);
3279        //
3280        // - You can't just mark the byte to be erased as `Tag::EMPTY`, because otherwise the `find_inner`
3281        //   function may stumble upon an `Tag::EMPTY` byte before finding the desired element and stop
3282        //   searching.
3283        //
3284        // Thus it is necessary to check all bytes after and before the erased element. If we are in
3285        // a contiguous `Group` of `FULL` or `Tag::DELETED` bytes (the number of `FULL` or `Tag::DELETED` bytes
3286        // before and after is greater than or equal to `Group::WIDTH`), then we must mark our byte as
3287        // `Tag::DELETED` in order for the `find_inner` function to go further. On the other hand, if there
3288        // is at least one `Tag::EMPTY` slot in the `Group`, then the `find_inner` function will still stumble
3289        // upon an `Tag::EMPTY` byte, so we can safely mark our erased byte as `Tag::EMPTY` as well.
3290        //
3291        // Finally, since `index_before == (index.wrapping_sub(Group::WIDTH) & self.bucket_mask) == index`
3292        // and given all of the above, tables smaller than the group width (self.buckets() < Group::WIDTH)
3293        // cannot have `Tag::DELETED` bytes.
3294        //
3295        // Note that in this context `leading_zeros` refers to the bytes at the end of a group, while
3296        // `trailing_zeros` refers to the bytes at the beginning of a group.
3297        let ctrl = if empty_before.leading_zeros() + empty_after.trailing_zeros() >= Group::WIDTH {
3298            Tag::DELETED
3299        } else {
3300            self.growth_left += 1;
3301            Tag::EMPTY
3302        };
3303        // SAFETY: the caller must uphold the safety contract for `erase` method.
3304        self.set_ctrl(index, ctrl);
3305        self.items -= 1;
3306    }
3307}
3308
3309impl<T: Clone, A: Allocator + Clone> Clone for RawTable<T, A> {
3310    fn clone(&self) -> Self {
3311        if self.table.is_empty_singleton() {
3312            Self::new_in(self.alloc.clone())
3313        } else {
3314            unsafe {
3315                // Avoid `Result::ok_or_else` because it bloats LLVM IR.
3316                //
3317                // SAFETY: This is safe as we are taking the size of an already allocated table
3318                // and therefore capacity overflow cannot occur, `self.table.buckets()` is power
3319                // of two and all allocator errors will be caught inside `RawTableInner::new_uninitialized`.
3320                let mut new_table = match Self::new_uninitialized(
3321                    self.alloc.clone(),
3322                    self.table.buckets(),
3323                    Fallibility::Infallible,
3324                ) {
3325                    Ok(table) => table,
3326                    Err(_) => hint::unreachable_unchecked(),
3327                };
3328
3329                // Cloning elements may fail (the clone function may panic). But we don't
3330                // need to worry about uninitialized control bits, since:
3331                // 1. The number of items (elements) in the table is zero, which means that
3332                //    the control bits will not be read by Drop function.
3333                // 2. The `clone_from_spec` method will first copy all control bits from
3334                //    `self` (thus initializing them). But this will not affect the `Drop`
3335                //    function, since the `clone_from_spec` function sets `items` only after
3336                //    successfully cloning all elements.
3337                new_table.clone_from_spec(self);
3338                new_table
3339            }
3340        }
3341    }
3342
3343    fn clone_from(&mut self, source: &Self) {
3344        if source.table.is_empty_singleton() {
3345            let mut old_inner = mem::replace(&mut self.table, RawTableInner::NEW);
3346            unsafe {
3347                // SAFETY:
3348                // 1. We call the function only once;
3349                // 2. We know for sure that `alloc` and `table_layout` matches the [`Allocator`]
3350                //    and [`TableLayout`] that were used to allocate this table.
3351                // 3. If any elements' drop function panics, then there will only be a memory leak,
3352                //    because we have replaced the inner table with a new one.
3353                old_inner.drop_inner_table::<T, _>(&self.alloc, Self::TABLE_LAYOUT);
3354            }
3355        } else {
3356            unsafe {
3357                // Make sure that if any panics occurs, we clear the table and
3358                // leave it in an empty state.
3359                let mut self_ = guard(self, |self_| {
3360                    self_.clear_no_drop();
3361                });
3362
3363                // First, drop all our elements without clearing the control
3364                // bytes. If this panics then the scope guard will clear the
3365                // table, leaking any elements that were not dropped yet.
3366                //
3367                // This leak is unavoidable: we can't try dropping more elements
3368                // since this could lead to another panic and abort the process.
3369                //
3370                // SAFETY: If something gets wrong we clear our table right after
3371                // dropping the elements, so there is no double drop, since `items`
3372                // will be equal to zero.
3373                self_.table.drop_elements::<T>();
3374
3375                // If necessary, resize our table to match the source.
3376                if self_.buckets() != source.buckets() {
3377                    let new_inner = match RawTableInner::new_uninitialized(
3378                        &self_.alloc,
3379                        Self::TABLE_LAYOUT,
3380                        source.buckets(),
3381                        Fallibility::Infallible,
3382                    ) {
3383                        Ok(table) => table,
3384                        Err(_) => hint::unreachable_unchecked(),
3385                    };
3386                    // Replace the old inner with new uninitialized one. It's ok, since if something gets
3387                    // wrong `ScopeGuard` will initialize all control bytes and leave empty table.
3388                    let mut old_inner = mem::replace(&mut self_.table, new_inner);
3389                    if !old_inner.is_empty_singleton() {
3390                        // SAFETY:
3391                        // 1. We have checked that our table is allocated.
3392                        // 2. We know for sure that `alloc` and `table_layout` matches
3393                        // the [`Allocator`] and [`TableLayout`] that were used to allocate this table.
3394                        old_inner.free_buckets(&self_.alloc, Self::TABLE_LAYOUT);
3395                    }
3396                }
3397
3398                // Cloning elements may fail (the clone function may panic), but the `ScopeGuard`
3399                // inside the `clone_from_impl` function will take care of that, dropping all
3400                // cloned elements if necessary. Our `ScopeGuard` will clear the table.
3401                self_.clone_from_spec(source);
3402
3403                // Disarm the scope guard if cloning was successful.
3404                ScopeGuard::into_inner(self_);
3405            }
3406        }
3407    }
3408}
3409
3410/// Specialization of `clone_from` for `Copy` types
3411trait RawTableClone {
3412    unsafe fn clone_from_spec(&mut self, source: &Self);
3413}
3414impl<T: Clone, A: Allocator + Clone> RawTableClone for RawTable<T, A> {
3415    default_fn! {
3416        #[cfg_attr(feature = "inline-more", inline)]
3417        unsafe fn clone_from_spec(&mut self, source: &Self) {
3418            self.clone_from_impl(source);
3419        }
3420    }
3421}
3422#[cfg(feature = "nightly")]
3423impl<T: core::clone::TrivialClone, A: Allocator + Clone> RawTableClone for RawTable<T, A> {
3424    #[cfg_attr(feature = "inline-more", inline)]
3425    unsafe fn clone_from_spec(&mut self, source: &Self) {
3426        source
3427            .table
3428            .ctrl(0)
3429            .copy_to_nonoverlapping(self.table.ctrl(0), self.table.num_ctrl_bytes());
3430        source
3431            .data_start()
3432            .as_ptr()
3433            .copy_to_nonoverlapping(self.data_start().as_ptr(), self.table.buckets());
3434
3435        self.table.items = source.table.items;
3436        self.table.growth_left = source.table.growth_left;
3437    }
3438}
3439
3440impl<T: Clone, A: Allocator + Clone> RawTable<T, A> {
3441    /// Common code for `clone` and `clone_from`. Assumes:
3442    /// - `self.buckets() == source.buckets()`.
3443    /// - Any existing elements have been dropped.
3444    /// - The control bytes are not initialized yet.
3445    #[cfg_attr(feature = "inline-more", inline)]
3446    unsafe fn clone_from_impl(&mut self, source: &Self) {
3447        // Copy the control bytes unchanged. We do this in a single pass
3448        source
3449            .table
3450            .ctrl(0)
3451            .copy_to_nonoverlapping(self.table.ctrl(0), self.table.num_ctrl_bytes());
3452
3453        // The cloning of elements may panic, in which case we need
3454        // to make sure we drop only the elements that have been
3455        // cloned so far.
3456        let mut guard = guard((0, &mut *self), |(index, self_)| {
3457            if T::NEEDS_DROP {
3458                for i in 0..*index {
3459                    if self_.is_bucket_full(i) {
3460                        self_.bucket(i).drop();
3461                    }
3462                }
3463            }
3464        });
3465
3466        for from in source.iter() {
3467            let index = source.bucket_index(&from);
3468            let to = guard.1.bucket(index);
3469            to.write(from.as_ref().clone());
3470
3471            // Update the index in case we need to unwind.
3472            guard.0 = index + 1;
3473        }
3474
3475        // Successfully cloned all items, no need to clean up.
3476        mem::forget(guard);
3477
3478        self.table.items = source.table.items;
3479        self.table.growth_left = source.table.growth_left;
3480    }
3481}
3482
3483impl<T, A: Allocator + Default> Default for RawTable<T, A> {
3484    #[inline]
3485    fn default() -> Self {
3486        Self::new_in(Default::default())
3487    }
3488}
3489
3490#[cfg(feature = "nightly")]
3491unsafe impl<#[may_dangle] T, A: Allocator> Drop for RawTable<T, A> {
3492    #[cfg_attr(feature = "inline-more", inline)]
3493    fn drop(&mut self) {
3494        unsafe {
3495            // SAFETY:
3496            // 1. We call the function only once;
3497            // 2. We know for sure that `alloc` and `table_layout` matches the [`Allocator`]
3498            //    and [`TableLayout`] that were used to allocate this table.
3499            // 3. If the drop function of any elements fails, then only a memory leak will occur,
3500            //    and we don't care because we are inside the `Drop` function of the `RawTable`,
3501            //    so there won't be any table left in an inconsistent state.
3502            self.table
3503                .drop_inner_table::<T, _>(&self.alloc, Self::TABLE_LAYOUT);
3504        }
3505    }
3506}
3507#[cfg(not(feature = "nightly"))]
3508impl<T, A: Allocator> Drop for RawTable<T, A> {
3509    #[cfg_attr(feature = "inline-more", inline)]
3510    fn drop(&mut self) {
3511        unsafe {
3512            // SAFETY:
3513            // 1. We call the function only once;
3514            // 2. We know for sure that `alloc` and `table_layout` matches the [`Allocator`]
3515            //    and [`TableLayout`] that were used to allocate this table.
3516            // 3. If the drop function of any elements fails, then only a memory leak will occur,
3517            //    and we don't care because we are inside the `Drop` function of the `RawTable`,
3518            //    so there won't be any table left in an inconsistent state.
3519            self.table
3520                .drop_inner_table::<T, _>(&self.alloc, Self::TABLE_LAYOUT);
3521        }
3522    }
3523}
3524
3525impl<T, A: Allocator> IntoIterator for RawTable<T, A> {
3526    type Item = T;
3527    type IntoIter = RawIntoIter<T, A>;
3528
3529    #[cfg_attr(feature = "inline-more", inline)]
3530    fn into_iter(self) -> RawIntoIter<T, A> {
3531        unsafe {
3532            let iter = self.iter();
3533            self.into_iter_from(iter)
3534        }
3535    }
3536}
3537
3538/// Iterator over a sub-range of a table. Unlike `RawIter` this iterator does
3539/// not track an item count.
3540pub(crate) struct RawIterRange<T> {
3541    // Mask of full buckets in the current group. Bits are cleared from this
3542    // mask as each element is processed.
3543    current_group: BitMaskIter,
3544
3545    // Pointer to the buckets for the current group.
3546    data: Bucket<T>,
3547
3548    // Pointer to the next group of control bytes,
3549    // Must be aligned to the group size.
3550    next_ctrl: *const u8,
3551
3552    // Pointer one past the last control byte of this range.
3553    end: *const u8,
3554}
3555
3556impl<T> RawIterRange<T> {
3557    /// Returns a `RawIterRange` covering a subset of a table.
3558    ///
3559    /// # Safety
3560    ///
3561    /// If any of the following conditions are violated, the result is
3562    /// [`undefined behavior`]:
3563    ///
3564    /// * `ctrl` must be [valid] for reads, i.e. table outlives the `RawIterRange`;
3565    ///
3566    /// * `ctrl` must be properly aligned to the group size (`Group::WIDTH`);
3567    ///
3568    /// * `ctrl` must point to the array of properly initialized control bytes;
3569    ///
3570    /// * `data` must be the [`Bucket`] at the `ctrl` index in the table;
3571    ///
3572    /// * the value of `len` must be less than or equal to the number of table buckets,
3573    ///   and the returned value of `ctrl.as_ptr().add(len).offset_from(ctrl.as_ptr())`
3574    ///   must be positive.
3575    ///
3576    /// * The `ctrl.add(len)` pointer must be either in bounds or one
3577    ///   byte past the end of the same [allocated table].
3578    ///
3579    /// * The `len` must be a power of two.
3580    ///
3581    /// [valid]: https://doc.rust-lang.org/std/ptr/index.html#safety
3582    /// [`undefined behavior`]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
3583    #[cfg_attr(feature = "inline-more", inline)]
3584    unsafe fn new(ctrl: *const u8, data: Bucket<T>, len: usize) -> Self {
3585        debug_assert_ne!(len, 0);
3586        debug_assert_eq!(ctrl as usize % Group::WIDTH, 0);
3587        // SAFETY: The caller must uphold the safety rules for the [`RawIterRange::new`]
3588        let end = ctrl.add(len);
3589
3590        // Load the first group and advance ctrl to point to the next group
3591        // SAFETY: The caller must uphold the safety rules for the [`RawIterRange::new`]
3592        let current_group = Group::load_aligned(ctrl.cast()).match_full();
3593        let next_ctrl = ctrl.add(Group::WIDTH);
3594
3595        Self {
3596            current_group: current_group.into_iter(),
3597            data,
3598            next_ctrl,
3599            end,
3600        }
3601    }
3602
3603    /// Splits a `RawIterRange` into two halves.
3604    ///
3605    /// Returns `None` if the remaining range is smaller than or equal to the
3606    /// group width.
3607    #[cfg_attr(feature = "inline-more", inline)]
3608    #[cfg(feature = "rayon")]
3609    pub(crate) fn split(mut self) -> (Self, Option<RawIterRange<T>>) {
3610        unsafe {
3611            if self.end <= self.next_ctrl {
3612                // Nothing to split if the group that we are current processing
3613                // is the last one.
3614                (self, None)
3615            } else {
3616                // len is the remaining number of elements after the group that
3617                // we are currently processing. It must be a multiple of the
3618                // group size (small tables are caught by the check above).
3619                let len = offset_from(self.end, self.next_ctrl);
3620                debug_assert_eq!(len % Group::WIDTH, 0);
3621
3622                // Split the remaining elements into two halves, but round the
3623                // midpoint down in case there is an odd number of groups
3624                // remaining. This ensures that:
3625                // - The tail is at least 1 group long.
3626                // - The split is roughly even considering we still have the
3627                //   current group to process.
3628                let mid = (len / 2) & !(Group::WIDTH - 1);
3629
3630                let tail = Self::new(
3631                    self.next_ctrl.add(mid),
3632                    self.data.next_n(Group::WIDTH).next_n(mid),
3633                    len - mid,
3634                );
3635                debug_assert_eq!(
3636                    self.data.next_n(Group::WIDTH).next_n(mid).ptr,
3637                    tail.data.ptr
3638                );
3639                debug_assert_eq!(self.end, tail.end);
3640                self.end = self.next_ctrl.add(mid);
3641                debug_assert_eq!(self.end.add(Group::WIDTH), tail.next_ctrl);
3642                (self, Some(tail))
3643            }
3644        }
3645    }
3646
3647    /// # Safety
3648    /// If `DO_CHECK_PTR_RANGE` is false, caller must ensure that we never try to iterate
3649    /// after yielding all elements.
3650    #[cfg_attr(feature = "inline-more", inline)]
3651    unsafe fn next_impl<const DO_CHECK_PTR_RANGE: bool>(&mut self) -> Option<Bucket<T>> {
3652        loop {
3653            if let Some(index) = self.current_group.next() {
3654                return Some(self.data.next_n(index));
3655            }
3656
3657            if DO_CHECK_PTR_RANGE && self.next_ctrl >= self.end {
3658                return None;
3659            }
3660
3661            // We might read past self.end up to the next group boundary,
3662            // but this is fine because it only occurs on tables smaller
3663            // than the group size where the trailing control bytes are all
3664            // EMPTY. On larger tables self.end is guaranteed to be aligned
3665            // to the group size (since tables are power-of-two sized).
3666            self.current_group = Group::load_aligned(self.next_ctrl.cast())
3667                .match_full()
3668                .into_iter();
3669            self.data = self.data.next_n(Group::WIDTH);
3670            self.next_ctrl = self.next_ctrl.add(Group::WIDTH);
3671        }
3672    }
3673
3674    /// Folds every element into an accumulator by applying an operation,
3675    /// returning the final result.
3676    ///
3677    /// `fold_impl()` takes three arguments: the number of items remaining in
3678    /// the iterator, an initial value, and a closure with two arguments: an
3679    /// 'accumulator', and an element. The closure returns the value that the
3680    /// accumulator should have for the next iteration.
3681    ///
3682    /// The initial value is the value the accumulator will have on the first call.
3683    ///
3684    /// After applying this closure to every element of the iterator, `fold_impl()`
3685    /// returns the accumulator.
3686    ///
3687    /// # Safety
3688    ///
3689    /// If any of the following conditions are violated, the result is
3690    /// [`Undefined Behavior`]:
3691    ///
3692    /// * The [`RawTableInner`] / [`RawTable`] must be alive and not moved,
3693    ///   i.e. table outlives the `RawIterRange`;
3694    ///
3695    /// * The provided `n` value must match the actual number of items
3696    ///   in the table.
3697    ///
3698    /// [`Undefined Behavior`]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
3699    #[allow(clippy::while_let_on_iterator)]
3700    #[cfg_attr(feature = "inline-more", inline)]
3701    unsafe fn fold_impl<F, B>(mut self, mut n: usize, mut acc: B, mut f: F) -> B
3702    where
3703        F: FnMut(B, Bucket<T>) -> B,
3704    {
3705        loop {
3706            while let Some(index) = self.current_group.next() {
3707                // The returned `index` will always be in the range `0..Group::WIDTH`,
3708                // so that calling `self.data.next_n(index)` is safe (see detailed explanation below).
3709                debug_assert!(n != 0);
3710                let bucket = self.data.next_n(index);
3711                acc = f(acc, bucket);
3712                n -= 1;
3713            }
3714
3715            if n == 0 {
3716                return acc;
3717            }
3718
3719            // SAFETY: The caller of this function ensures that:
3720            //
3721            // 1. The provided `n` value matches the actual number of items in the table;
3722            // 2. The table is alive and did not moved.
3723            //
3724            // Taking the above into account, we always stay within the bounds, because:
3725            //
3726            // 1. For tables smaller than the group width (self.buckets() <= Group::WIDTH),
3727            //    we will never end up in the given branch, since we should have already
3728            //    yielded all the elements of the table.
3729            //
3730            // 2. For tables larger than the group width. The number of buckets is a
3731            //    power of two (2 ^ n), Group::WIDTH is also power of two (2 ^ k). Since
3732            //    `(2 ^ n) > (2 ^ k)`, than `(2 ^ n) % (2 ^ k) = 0`. As we start from the
3733            //    start of the array of control bytes, and never try to iterate after
3734            //    getting all the elements, the last `self.current_group` will read bytes
3735            //    from the `self.buckets() - Group::WIDTH` index.  We know also that
3736            //    `self.current_group.next()` will always return indices within the range
3737            //    `0..Group::WIDTH`.
3738            //
3739            //    Knowing all of the above and taking into account that we are synchronizing
3740            //    the `self.data` index with the index we used to read the `self.current_group`,
3741            //    the subsequent `self.data.next_n(index)` will always return a bucket with
3742            //    an index number less than `self.buckets()`.
3743            //
3744            //    The last `self.next_ctrl`, whose index would be `self.buckets()`, will never
3745            //    actually be read, since we should have already yielded all the elements of
3746            //    the table.
3747            self.current_group = Group::load_aligned(self.next_ctrl.cast())
3748                .match_full()
3749                .into_iter();
3750            self.data = self.data.next_n(Group::WIDTH);
3751            self.next_ctrl = self.next_ctrl.add(Group::WIDTH);
3752        }
3753    }
3754}
3755
3756// We make raw iterators unconditionally Send and Sync, and let the PhantomData
3757// in the actual iterator implementations determine the real Send/Sync bounds.
3758unsafe impl<T> Send for RawIterRange<T> {}
3759unsafe impl<T> Sync for RawIterRange<T> {}
3760
3761impl<T> Clone for RawIterRange<T> {
3762    #[cfg_attr(feature = "inline-more", inline)]
3763    fn clone(&self) -> Self {
3764        Self {
3765            data: self.data.clone(),
3766            next_ctrl: self.next_ctrl,
3767            current_group: self.current_group.clone(),
3768            end: self.end,
3769        }
3770    }
3771}
3772
3773impl<T> Iterator for RawIterRange<T> {
3774    type Item = Bucket<T>;
3775
3776    #[cfg_attr(feature = "inline-more", inline)]
3777    fn next(&mut self) -> Option<Bucket<T>> {
3778        unsafe {
3779            // SAFETY: We set checker flag to true.
3780            self.next_impl::<true>()
3781        }
3782    }
3783
3784    #[inline]
3785    fn size_hint(&self) -> (usize, Option<usize>) {
3786        // We don't have an item count, so just guess based on the range size.
3787        let remaining_buckets = if self.end > self.next_ctrl {
3788            unsafe { offset_from(self.end, self.next_ctrl) }
3789        } else {
3790            0
3791        };
3792
3793        // Add a group width to include the group we are currently processing.
3794        (0, Some(Group::WIDTH + remaining_buckets))
3795    }
3796}
3797
3798impl<T> FusedIterator for RawIterRange<T> {}
3799
3800/// Iterator which returns a raw pointer to every full bucket in the table.
3801///
3802/// For maximum flexibility this iterator is not bound by a lifetime, but you
3803/// must observe several rules when using it:
3804/// - You must not free the hash table while iterating (including via growing/shrinking).
3805/// - It is fine to erase a bucket that has been yielded by the iterator.
3806/// - Erasing a bucket that has not yet been yielded by the iterator may still
3807///   result in the iterator yielding that bucket (unless `reflect_remove` is called).
3808/// - It is unspecified whether an element inserted after the iterator was
3809///   created will be yielded by that iterator (unless `reflect_insert` is called).
3810/// - The order in which the iterator yields bucket is unspecified and may
3811///   change in the future.
3812pub struct RawIter<T> {
3813    pub(crate) iter: RawIterRange<T>,
3814    items: usize,
3815}
3816
3817impl<T> RawIter<T> {
3818    unsafe fn drop_elements(&mut self) {
3819        if T::NEEDS_DROP && self.items != 0 {
3820            for item in self {
3821                item.drop();
3822            }
3823        }
3824    }
3825}
3826
3827impl<T> Clone for RawIter<T> {
3828    #[cfg_attr(feature = "inline-more", inline)]
3829    fn clone(&self) -> Self {
3830        Self {
3831            iter: self.iter.clone(),
3832            items: self.items,
3833        }
3834    }
3835}
3836impl<T> Default for RawIter<T> {
3837    #[cfg_attr(feature = "inline-more", inline)]
3838    fn default() -> Self {
3839        // SAFETY: Because the table is static, it always outlives the iter.
3840        unsafe { RawTableInner::NEW.iter() }
3841    }
3842}
3843
3844impl<T> Iterator for RawIter<T> {
3845    type Item = Bucket<T>;
3846
3847    #[cfg_attr(feature = "inline-more", inline)]
3848    fn next(&mut self) -> Option<Bucket<T>> {
3849        // Inner iterator iterates over buckets
3850        // so it can do unnecessary work if we already yielded all items.
3851        if self.items == 0 {
3852            return None;
3853        }
3854
3855        let nxt = unsafe {
3856            // SAFETY: We check number of items to yield using `items` field.
3857            self.iter.next_impl::<false>()
3858        };
3859
3860        debug_assert!(nxt.is_some());
3861        self.items -= 1;
3862
3863        nxt
3864    }
3865
3866    #[inline]
3867    fn size_hint(&self) -> (usize, Option<usize>) {
3868        (self.items, Some(self.items))
3869    }
3870
3871    #[inline]
3872    fn fold<B, F>(self, init: B, f: F) -> B
3873    where
3874        Self: Sized,
3875        F: FnMut(B, Self::Item) -> B,
3876    {
3877        unsafe { self.iter.fold_impl(self.items, init, f) }
3878    }
3879}
3880
3881impl<T> ExactSizeIterator for RawIter<T> {}
3882impl<T> FusedIterator for RawIter<T> {}
3883
3884/// Iterator which returns an index of every full bucket in the table.
3885///
3886/// For maximum flexibility this iterator is not bound by a lifetime, but you
3887/// must observe several rules when using it:
3888/// - You must not free the hash table while iterating (including via growing/shrinking).
3889/// - It is fine to erase a bucket that has been yielded by the iterator.
3890/// - Erasing a bucket that has not yet been yielded by the iterator may still
3891///   result in the iterator yielding index of that bucket.
3892/// - It is unspecified whether an element inserted after the iterator was
3893///   created will be yielded by that iterator.
3894/// - The order in which the iterator yields indices of the buckets is unspecified
3895///   and may change in the future.
3896#[derive(Clone)]
3897pub(crate) struct FullBucketsIndices {
3898    // Mask of full buckets in the current group. Bits are cleared from this
3899    // mask as each element is processed.
3900    current_group: BitMaskIter,
3901
3902    // Initial value of the bytes' indices of the current group (relative
3903    // to the start of the control bytes).
3904    group_first_index: usize,
3905
3906    // Pointer to the current group of control bytes,
3907    // Must be aligned to the group size (Group::WIDTH).
3908    ctrl: NonNull<u8>,
3909
3910    // Number of elements in the table.
3911    items: usize,
3912}
3913
3914impl Default for FullBucketsIndices {
3915    #[cfg_attr(feature = "inline-more", inline)]
3916    fn default() -> Self {
3917        // SAFETY: Because the table is static, it always outlives the iter.
3918        unsafe { RawTableInner::NEW.full_buckets_indices() }
3919    }
3920}
3921
3922impl FullBucketsIndices {
3923    /// Advances the iterator and returns the next value.
3924    ///
3925    /// # Safety
3926    ///
3927    /// If any of the following conditions are violated, the result is
3928    /// [`Undefined Behavior`]:
3929    ///
3930    /// * The [`RawTableInner`] / [`RawTable`] must be alive and not moved,
3931    ///   i.e. table outlives the `FullBucketsIndices`;
3932    ///
3933    /// * It never tries to iterate after getting all elements.
3934    ///
3935    /// [`Undefined Behavior`]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
3936    #[inline(always)]
3937    unsafe fn next_impl(&mut self) -> Option<usize> {
3938        loop {
3939            if let Some(index) = self.current_group.next() {
3940                // The returned `self.group_first_index + index` will always
3941                // be in the range `0..self.buckets()`. See explanation below.
3942                return Some(self.group_first_index + index);
3943            }
3944
3945            // SAFETY: The caller of this function ensures that:
3946            //
3947            // 1. It never tries to iterate after getting all the elements;
3948            // 2. The table is alive and did not moved;
3949            // 3. The first `self.ctrl` pointed to the start of the array of control bytes.
3950            //
3951            // Taking the above into account, we always stay within the bounds, because:
3952            //
3953            // 1. For tables smaller than the group width (self.buckets() <= Group::WIDTH),
3954            //    we will never end up in the given branch, since we should have already
3955            //    yielded all the elements of the table.
3956            //
3957            // 2. For tables larger than the group width. The number of buckets is a
3958            //    power of two (2 ^ n), Group::WIDTH is also power of two (2 ^ k). Since
3959            //    `(2 ^ n) > (2 ^ k)`, than `(2 ^ n) % (2 ^ k) = 0`. As we start from the
3960            //    the start of the array of control bytes, and never try to iterate after
3961            //    getting all the elements, the last `self.ctrl` will be equal to
3962            //    the `self.buckets() - Group::WIDTH`, so `self.current_group.next()`
3963            //    will always contains indices within the range `0..Group::WIDTH`,
3964            //    and subsequent `self.group_first_index + index` will always return a
3965            //    number less than `self.buckets()`.
3966            self.ctrl = NonNull::new_unchecked(self.ctrl.as_ptr().add(Group::WIDTH));
3967
3968            // SAFETY: See explanation above.
3969            self.current_group = Group::load_aligned(self.ctrl.as_ptr().cast())
3970                .match_full()
3971                .into_iter();
3972            self.group_first_index += Group::WIDTH;
3973        }
3974    }
3975}
3976
3977impl Iterator for FullBucketsIndices {
3978    type Item = usize;
3979
3980    /// Advances the iterator and returns the next value. It is up to
3981    /// the caller to ensure that the `RawTable` outlives the `FullBucketsIndices`,
3982    /// because we cannot make the `next` method unsafe.
3983    #[inline(always)]
3984    fn next(&mut self) -> Option<usize> {
3985        // Return if we already yielded all items.
3986        if self.items == 0 {
3987            return None;
3988        }
3989
3990        let nxt = unsafe {
3991            // SAFETY:
3992            // 1. We check number of items to yield using `items` field.
3993            // 2. The caller ensures that the table is alive and has not moved.
3994            self.next_impl()
3995        };
3996
3997        debug_assert!(nxt.is_some());
3998        self.items -= 1;
3999
4000        nxt
4001    }
4002
4003    #[inline(always)]
4004    fn size_hint(&self) -> (usize, Option<usize>) {
4005        (self.items, Some(self.items))
4006    }
4007}
4008
4009impl ExactSizeIterator for FullBucketsIndices {}
4010impl FusedIterator for FullBucketsIndices {}
4011
4012/// Iterator which consumes a table and returns elements.
4013pub struct RawIntoIter<T, A: Allocator = Global> {
4014    iter: RawIter<T>,
4015    allocation: Option<(NonNull<u8>, Layout, A)>,
4016    marker: PhantomData<T>,
4017}
4018
4019impl<T, A: Allocator> RawIntoIter<T, A> {
4020    #[cfg_attr(feature = "inline-more", inline)]
4021    pub fn iter(&self) -> RawIter<T> {
4022        self.iter.clone()
4023    }
4024}
4025
4026unsafe impl<T, A: Allocator> Send for RawIntoIter<T, A>
4027where
4028    T: Send,
4029    A: Send,
4030{
4031}
4032unsafe impl<T, A: Allocator> Sync for RawIntoIter<T, A>
4033where
4034    T: Sync,
4035    A: Sync,
4036{
4037}
4038
4039#[cfg(feature = "nightly")]
4040unsafe impl<#[may_dangle] T, A: Allocator> Drop for RawIntoIter<T, A> {
4041    #[cfg_attr(feature = "inline-more", inline)]
4042    fn drop(&mut self) {
4043        unsafe {
4044            // Drop all remaining elements
4045            self.iter.drop_elements();
4046
4047            // Free the table
4048            if let Some((ptr, layout, ref alloc)) = self.allocation {
4049                alloc.deallocate(ptr, layout);
4050            }
4051        }
4052    }
4053}
4054#[cfg(not(feature = "nightly"))]
4055impl<T, A: Allocator> Drop for RawIntoIter<T, A> {
4056    #[cfg_attr(feature = "inline-more", inline)]
4057    fn drop(&mut self) {
4058        unsafe {
4059            // Drop all remaining elements
4060            self.iter.drop_elements();
4061
4062            // Free the table
4063            if let Some((ptr, layout, ref alloc)) = self.allocation {
4064                alloc.deallocate(ptr, layout);
4065            }
4066        }
4067    }
4068}
4069
4070impl<T, A: Allocator> Default for RawIntoIter<T, A> {
4071    fn default() -> Self {
4072        Self {
4073            iter: Default::default(),
4074            allocation: None,
4075            marker: PhantomData,
4076        }
4077    }
4078}
4079impl<T, A: Allocator> Iterator for RawIntoIter<T, A> {
4080    type Item = T;
4081
4082    #[cfg_attr(feature = "inline-more", inline)]
4083    fn next(&mut self) -> Option<T> {
4084        unsafe { Some(self.iter.next()?.read()) }
4085    }
4086
4087    #[inline]
4088    fn size_hint(&self) -> (usize, Option<usize>) {
4089        self.iter.size_hint()
4090    }
4091}
4092
4093impl<T, A: Allocator> ExactSizeIterator for RawIntoIter<T, A> {}
4094impl<T, A: Allocator> FusedIterator for RawIntoIter<T, A> {}
4095
4096/// Iterator which consumes elements without freeing the table storage.
4097pub struct RawDrain<'a, T, A: Allocator = Global> {
4098    iter: RawIter<T>,
4099
4100    // The table is moved into the iterator for the duration of the drain. This
4101    // ensures that an empty table is left if the drain iterator is leaked
4102    // without dropping.
4103    table: RawTableInner,
4104    orig_table: NonNull<RawTableInner>,
4105
4106    // We don't use a &'a mut RawTable<T> because we want RawDrain to be
4107    // covariant over T.
4108    marker: PhantomData<&'a RawTable<T, A>>,
4109}
4110
4111impl<T, A: Allocator> RawDrain<'_, T, A> {
4112    #[cfg_attr(feature = "inline-more", inline)]
4113    pub fn iter(&self) -> RawIter<T> {
4114        self.iter.clone()
4115    }
4116}
4117
4118unsafe impl<T, A: Allocator> Send for RawDrain<'_, T, A>
4119where
4120    T: Send,
4121    A: Send,
4122{
4123}
4124unsafe impl<T, A: Allocator> Sync for RawDrain<'_, T, A>
4125where
4126    T: Sync,
4127    A: Sync,
4128{
4129}
4130
4131impl<T, A: Allocator> Drop for RawDrain<'_, T, A> {
4132    #[cfg_attr(feature = "inline-more", inline)]
4133    fn drop(&mut self) {
4134        unsafe {
4135            // Drop all remaining elements. Note that this may panic.
4136            self.iter.drop_elements();
4137
4138            // Reset the contents of the table now that all elements have been
4139            // dropped.
4140            self.table.clear_no_drop();
4141
4142            // Move the now empty table back to its original location.
4143            self.orig_table
4144                .as_ptr()
4145                .copy_from_nonoverlapping(&self.table, 1);
4146        }
4147    }
4148}
4149
4150impl<T, A: Allocator> Iterator for RawDrain<'_, T, A> {
4151    type Item = T;
4152
4153    #[cfg_attr(feature = "inline-more", inline)]
4154    fn next(&mut self) -> Option<T> {
4155        unsafe {
4156            let item = self.iter.next()?;
4157            Some(item.read())
4158        }
4159    }
4160
4161    #[inline]
4162    fn size_hint(&self) -> (usize, Option<usize>) {
4163        self.iter.size_hint()
4164    }
4165}
4166
4167impl<T, A: Allocator> ExactSizeIterator for RawDrain<'_, T, A> {}
4168impl<T, A: Allocator> FusedIterator for RawDrain<'_, T, A> {}
4169
4170/// Iterator over occupied buckets that could match a given hash.
4171///
4172/// `RawTable` only stores 7 bits of the hash value, so this iterator may return
4173/// items that have a hash value different than the one provided. You should
4174/// always validate the returned values before using them.
4175///
4176/// For maximum flexibility this iterator is not bound by a lifetime, but you
4177/// must observe several rules when using it:
4178/// - You must not free the hash table while iterating (including via growing/shrinking).
4179/// - It is fine to erase a bucket that has been yielded by the iterator.
4180/// - Erasing a bucket that has not yet been yielded by the iterator may still
4181///   result in the iterator yielding that bucket.
4182/// - It is unspecified whether an element inserted after the iterator was
4183///   created will be yielded by that iterator.
4184/// - The order in which the iterator yields buckets is unspecified and may
4185///   change in the future.
4186pub struct RawIterHash<T> {
4187    inner: RawIterHashIndices,
4188    _marker: PhantomData<T>,
4189}
4190
4191#[derive(Clone)]
4192pub(crate) struct RawIterHashIndices {
4193    // See `RawTableInner`'s corresponding fields for details.
4194    // We can't store a `*const RawTableInner` as it would get
4195    // invalidated by the user calling `&mut` methods on `RawTable`.
4196    bucket_mask: usize,
4197    ctrl: NonNull<u8>,
4198
4199    // The top 7 bits of the hash.
4200    tag_hash: Tag,
4201
4202    // The sequence of groups to probe in the search.
4203    probe_seq: ProbeSeq,
4204
4205    group: Group,
4206
4207    // The elements within the group with a matching tag-hash.
4208    bitmask: BitMaskIter,
4209}
4210
4211impl<T> RawIterHash<T> {
4212    #[cfg_attr(feature = "inline-more", inline)]
4213    unsafe fn new<A: Allocator>(table: &RawTable<T, A>, hash: u64) -> Self {
4214        RawIterHash {
4215            inner: RawIterHashIndices::new(&table.table, hash),
4216            _marker: PhantomData,
4217        }
4218    }
4219}
4220
4221impl<T> Clone for RawIterHash<T> {
4222    #[cfg_attr(feature = "inline-more", inline)]
4223    fn clone(&self) -> Self {
4224        Self {
4225            inner: self.inner.clone(),
4226            _marker: PhantomData,
4227        }
4228    }
4229}
4230
4231impl<T> Default for RawIterHash<T> {
4232    #[cfg_attr(feature = "inline-more", inline)]
4233    fn default() -> Self {
4234        Self {
4235            inner: RawIterHashIndices::default(),
4236            _marker: PhantomData,
4237        }
4238    }
4239}
4240
4241impl Default for RawIterHashIndices {
4242    #[cfg_attr(feature = "inline-more", inline)]
4243    fn default() -> Self {
4244        // SAFETY: Because the table is static, it always outlives the iter.
4245        unsafe { RawIterHashIndices::new(&RawTableInner::NEW, 0) }
4246    }
4247}
4248
4249impl RawIterHashIndices {
4250    #[cfg_attr(feature = "inline-more", inline)]
4251    unsafe fn new(table: &RawTableInner, hash: u64) -> Self {
4252        let tag_hash = Tag::full(hash);
4253        let probe_seq = table.probe_seq(hash);
4254        let group = Group::load(table.ctrl(probe_seq.pos));
4255        let bitmask = group.match_tag(tag_hash).into_iter();
4256
4257        RawIterHashIndices {
4258            bucket_mask: table.bucket_mask,
4259            ctrl: table.ctrl,
4260            tag_hash,
4261            probe_seq,
4262            group,
4263            bitmask,
4264        }
4265    }
4266}
4267
4268impl<T> Iterator for RawIterHash<T> {
4269    type Item = Bucket<T>;
4270
4271    fn next(&mut self) -> Option<Bucket<T>> {
4272        unsafe {
4273            match self.inner.next() {
4274                Some(index) => {
4275                    // Can't use `RawTable::bucket` here as we don't have
4276                    // an actual `RawTable` reference to use.
4277                    debug_assert!(index <= self.inner.bucket_mask);
4278                    let bucket = Bucket::from_base_index(self.inner.ctrl.cast(), index);
4279                    Some(bucket)
4280                }
4281                None => None,
4282            }
4283        }
4284    }
4285}
4286
4287impl Iterator for RawIterHashIndices {
4288    type Item = usize;
4289
4290    fn next(&mut self) -> Option<Self::Item> {
4291        unsafe {
4292            loop {
4293                if let Some(bit) = self.bitmask.next() {
4294                    let index = (self.probe_seq.pos + bit) & self.bucket_mask;
4295                    return Some(index);
4296                }
4297                if likely(self.group.match_empty().any_bit_set()) {
4298                    return None;
4299                }
4300                self.probe_seq.move_next(self.bucket_mask);
4301
4302                // Can't use `RawTableInner::ctrl` here as we don't have
4303                // an actual `RawTableInner` reference to use.
4304                let index = self.probe_seq.pos;
4305                debug_assert!(index < self.bucket_mask + 1 + Group::WIDTH);
4306                let group_ctrl = self.ctrl.as_ptr().add(index).cast();
4307
4308                self.group = Group::load(group_ctrl);
4309                self.bitmask = self.group.match_tag(self.tag_hash).into_iter();
4310            }
4311        }
4312    }
4313}
4314
4315pub(crate) struct RawExtractIf<'a, T, A: Allocator> {
4316    pub iter: RawIter<T>,
4317    pub table: &'a mut RawTable<T, A>,
4318}
4319
4320impl<T, A: Allocator> RawExtractIf<'_, T, A> {
4321    #[cfg_attr(feature = "inline-more", inline)]
4322    pub(crate) fn next<F>(&mut self, mut f: F) -> Option<T>
4323    where
4324        F: FnMut(&mut T) -> bool,
4325    {
4326        unsafe {
4327            for item in &mut self.iter {
4328                if f(item.as_mut()) {
4329                    return Some(self.table.remove(item).0);
4330                }
4331            }
4332        }
4333        None
4334    }
4335}
4336
4337#[cfg(test)]
4338mod test_map {
4339    use super::*;
4340
4341    #[test]
4342    fn test_prev_pow2() {
4343        // Skip 0, not defined for that input.
4344        let mut pow2: usize = 1;
4345        while (pow2 << 1) > 0 {
4346            let next_pow2 = pow2 << 1;
4347            assert_eq!(pow2, prev_pow2(pow2));
4348            // Need to skip 2, because it's also a power of 2, so it doesn't
4349            // return the previous power of 2.
4350            if next_pow2 > 2 {
4351                assert_eq!(pow2, prev_pow2(pow2 + 1));
4352                assert_eq!(pow2, prev_pow2(next_pow2 - 1));
4353            }
4354            pow2 = next_pow2;
4355        }
4356    }
4357
4358    #[test]
4359    fn test_minimum_capacity_for_small_types() {
4360        #[track_caller]
4361        fn test_t<T>() {
4362            let raw_table: RawTable<T> = RawTable::with_capacity(1);
4363            let actual_buckets = raw_table.buckets();
4364            let min_buckets = Group::WIDTH / core::mem::size_of::<T>();
4365            assert!(
4366                actual_buckets >= min_buckets,
4367                "expected at least {min_buckets} buckets, got {actual_buckets} buckets"
4368            );
4369        }
4370
4371        test_t::<u8>();
4372
4373        // This is only "small" for some platforms, like x86_64 with SSE2, but
4374        // there's no harm in running it on other platforms.
4375        test_t::<u16>();
4376    }
4377
4378    fn rehash_in_place<T>(table: &mut RawTable<T>, hasher: impl Fn(&T) -> u64) {
4379        unsafe {
4380            table.table.rehash_in_place(
4381                &|table, index| hasher(table.bucket::<T>(index).as_ref()),
4382                mem::size_of::<T>(),
4383                if mem::needs_drop::<T>() {
4384                    Some(|ptr| ptr::drop_in_place(ptr as *mut T))
4385                } else {
4386                    None
4387                },
4388            );
4389        }
4390    }
4391
4392    #[test]
4393    fn rehash() {
4394        let mut table = RawTable::new();
4395        let hasher = |i: &u64| *i;
4396        for i in 0..100 {
4397            table.insert(i, i, hasher);
4398        }
4399
4400        for i in 0..100 {
4401            unsafe {
4402                assert_eq!(table.find(i, |x| *x == i).map(|b| b.read()), Some(i));
4403            }
4404            assert!(table.find(i + 100, |x| *x == i + 100).is_none());
4405        }
4406
4407        rehash_in_place(&mut table, hasher);
4408
4409        for i in 0..100 {
4410            unsafe {
4411                assert_eq!(table.find(i, |x| *x == i).map(|b| b.read()), Some(i));
4412            }
4413            assert!(table.find(i + 100, |x| *x == i + 100).is_none());
4414        }
4415    }
4416
4417    /// CHECKING THAT WE ARE NOT TRYING TO READ THE MEMORY OF
4418    /// AN UNINITIALIZED TABLE DURING THE DROP
4419    #[test]
4420    fn test_drop_uninitialized() {
4421        use ::alloc::vec::Vec;
4422
4423        let table = unsafe {
4424            // SAFETY: The `buckets` is power of two and we're not
4425            // trying to actually use the returned RawTable.
4426            RawTable::<(u64, Vec<i32>)>::new_uninitialized(Global, 8, Fallibility::Infallible)
4427                .unwrap()
4428        };
4429        drop(table);
4430    }
4431
4432    /// CHECKING THAT WE DON'T TRY TO DROP DATA IF THE `ITEMS`
4433    /// ARE ZERO, EVEN IF WE HAVE `FULL` CONTROL BYTES.
4434    #[test]
4435    fn test_drop_zero_items() {
4436        use ::alloc::vec::Vec;
4437        unsafe {
4438            // SAFETY: The `buckets` is power of two and we're not
4439            // trying to actually use the returned RawTable.
4440            let mut table =
4441                RawTable::<(u64, Vec<i32>)>::new_uninitialized(Global, 8, Fallibility::Infallible)
4442                    .unwrap();
4443
4444            // WE SIMULATE, AS IT WERE, A FULL TABLE.
4445
4446            // SAFETY: We checked that the table is allocated and therefore the table already has
4447            // `self.bucket_mask + 1 + Group::WIDTH` number of control bytes (see TableLayout::calculate_layout_for)
4448            // so writing `table.table.num_ctrl_bytes() == bucket_mask + 1 + Group::WIDTH` bytes is safe.
4449            table.table.ctrl_slice().fill_empty();
4450
4451            // SAFETY: table.capacity() is guaranteed to be smaller than table.buckets()
4452            table.table.ctrl(0).write_bytes(0, table.capacity());
4453
4454            // Fix up the trailing control bytes. See the comments in set_ctrl
4455            // for the handling of tables smaller than the group width.
4456            if table.buckets() < Group::WIDTH {
4457                // SAFETY: We have `self.bucket_mask + 1 + Group::WIDTH` number of control bytes,
4458                // so copying `self.buckets() == self.bucket_mask + 1` bytes with offset equal to
4459                // `Group::WIDTH` is safe
4460                table
4461                    .table
4462                    .ctrl(0)
4463                    .copy_to(table.table.ctrl(Group::WIDTH), table.table.buckets());
4464            } else {
4465                // SAFETY: We have `self.bucket_mask + 1 + Group::WIDTH` number of
4466                // control bytes,so copying `Group::WIDTH` bytes with offset equal
4467                // to `self.buckets() == self.bucket_mask + 1` is safe
4468                table
4469                    .table
4470                    .ctrl(0)
4471                    .copy_to(table.table.ctrl(table.table.buckets()), Group::WIDTH);
4472            }
4473            drop(table);
4474        }
4475    }
4476
4477    /// CHECKING THAT WE DON'T TRY TO DROP DATA IF THE `ITEMS`
4478    /// ARE ZERO, EVEN IF WE HAVE `FULL` CONTROL BYTES.
4479    #[test]
4480    fn test_catch_panic_clone_from() {
4481        use super::{AllocError, Allocator, Global};
4482        use ::alloc::sync::Arc;
4483        use ::alloc::vec::Vec;
4484        use core::sync::atomic::{AtomicI8, Ordering};
4485        use std::thread;
4486
4487        struct MyAllocInner {
4488            drop_count: Arc<AtomicI8>,
4489        }
4490
4491        #[derive(Clone)]
4492        struct MyAlloc {
4493            _inner: Arc<MyAllocInner>,
4494        }
4495
4496        impl Drop for MyAllocInner {
4497            fn drop(&mut self) {
4498                println!("MyAlloc freed.");
4499                self.drop_count.fetch_sub(1, Ordering::SeqCst);
4500            }
4501        }
4502
4503        unsafe impl Allocator for MyAlloc {
4504            fn allocate(&self, layout: Layout) -> std::result::Result<NonNull<[u8]>, AllocError> {
4505                let g = Global;
4506                g.allocate(layout)
4507            }
4508
4509            unsafe fn deallocate(&self, ptr: NonNull<u8>, layout: Layout) {
4510                let g = Global;
4511                g.deallocate(ptr, layout)
4512            }
4513        }
4514
4515        const DISARMED: bool = false;
4516        const ARMED: bool = true;
4517
4518        struct CheckedCloneDrop {
4519            panic_in_clone: bool,
4520            dropped: bool,
4521            need_drop: Vec<u64>,
4522        }
4523
4524        impl Clone for CheckedCloneDrop {
4525            fn clone(&self) -> Self {
4526                if self.panic_in_clone {
4527                    panic!("panic in clone")
4528                }
4529                Self {
4530                    panic_in_clone: self.panic_in_clone,
4531                    dropped: self.dropped,
4532                    need_drop: self.need_drop.clone(),
4533                }
4534            }
4535        }
4536
4537        impl Drop for CheckedCloneDrop {
4538            fn drop(&mut self) {
4539                if self.dropped {
4540                    panic!("double drop");
4541                }
4542                self.dropped = true;
4543            }
4544        }
4545
4546        let dropped: Arc<AtomicI8> = Arc::new(AtomicI8::new(2));
4547
4548        let mut table = RawTable::new_in(MyAlloc {
4549            _inner: Arc::new(MyAllocInner {
4550                drop_count: dropped.clone(),
4551            }),
4552        });
4553
4554        for (idx, panic_in_clone) in core::iter::repeat(DISARMED).take(7).enumerate() {
4555            let idx = idx as u64;
4556            table.insert(
4557                idx,
4558                (
4559                    idx,
4560                    CheckedCloneDrop {
4561                        panic_in_clone,
4562                        dropped: false,
4563                        need_drop: vec![idx],
4564                    },
4565                ),
4566                |(k, _)| *k,
4567            );
4568        }
4569
4570        assert_eq!(table.len(), 7);
4571
4572        thread::scope(|s| {
4573            let result = s.spawn(|| {
4574                let armed_flags = [
4575                    DISARMED, DISARMED, ARMED, DISARMED, DISARMED, DISARMED, DISARMED,
4576                ];
4577                let mut scope_table = RawTable::new_in(MyAlloc {
4578                    _inner: Arc::new(MyAllocInner {
4579                        drop_count: dropped.clone(),
4580                    }),
4581                });
4582                for (idx, &panic_in_clone) in armed_flags.iter().enumerate() {
4583                    let idx = idx as u64;
4584                    scope_table.insert(
4585                        idx,
4586                        (
4587                            idx,
4588                            CheckedCloneDrop {
4589                                panic_in_clone,
4590                                dropped: false,
4591                                need_drop: vec![idx + 100],
4592                            },
4593                        ),
4594                        |(k, _)| *k,
4595                    );
4596                }
4597                table.clone_from(&scope_table);
4598            });
4599            assert!(result.join().is_err());
4600        });
4601
4602        // Let's check that all iterators work fine and do not return elements
4603        // (especially `RawIterRange`, which does not depend on the number of
4604        // elements in the table, but looks directly at the control bytes)
4605        //
4606        // SAFETY: We know for sure that `RawTable` will outlive
4607        // the returned `RawIter / RawIterRange` iterator.
4608        assert_eq!(table.len(), 0);
4609        assert_eq!(unsafe { table.iter().count() }, 0);
4610        assert_eq!(unsafe { table.iter().iter.count() }, 0);
4611
4612        for idx in 0..table.buckets() {
4613            let idx = idx as u64;
4614            assert!(
4615                table.find(idx, |(k, _)| *k == idx).is_none(),
4616                "Index: {idx}"
4617            );
4618        }
4619
4620        // All allocator clones should already be dropped.
4621        assert_eq!(dropped.load(Ordering::SeqCst), 1);
4622    }
4623}