use core::{fmt, iter::FusedIterator, marker::PhantomData};

use crate::{
    raw::{
        Allocator, Bucket, Global, InsertSlot, RawDrain, RawExtractIf, RawIntoIter, RawIter,
        RawTable,
    },
    TryReserveError,
};

/// Low-level hash table with explicit hashing.
///
/// The primary use case for this type over [`HashMap`] or [`HashSet`] is to
/// support types that do not implement the [`Hash`] and [`Eq`] traits, but
/// instead require additional data not contained in the key itself to compute a
/// hash and compare two elements for equality.
///
/// Examples of when this can be useful include:
/// - An `IndexMap` implementation where indices into a `Vec` are stored as
///   elements in a `HashTable<usize>`. Hashing and comparing the elements
///   requires indexing the associated `Vec` to get the actual value referred to
///   by the index.
/// - Avoiding re-computing a hash when it is already known.
/// - Mutating the key of an element in a way that doesn't affect its hash.
///
/// To achieve this, `HashTable` methods that search for an element in the table
/// require a hash value and equality function to be explicitly passed in as
/// arguments. The method will then iterate over the elements with the given
/// hash and call the equality function on each of them, until a match is found.
///
/// In most cases, a `HashTable` will not be exposed directly in an API. It will
/// instead be wrapped in a helper type which handles the work of calculating
/// hash values and comparing elements.
///
/// Due to its low-level nature, this type provides fewer guarantees than
/// [`HashMap`] and [`HashSet`]. Specifically, the API allows you to shoot
/// yourself in the foot by having multiple elements with identical keys in the
/// table. The table itself will still function correctly and lookups will
/// arbitrarily return one of the matching elements. However you should avoid
/// doing this because it changes the runtime of hash table operations from
/// `O(1)` to `O(k)` where `k` is the number of duplicate entries.
///
/// [`HashMap`]: super::HashMap
/// [`HashSet`]: super::HashSet
pub struct HashTable<T, A = Global>
where
    A: Allocator,
{
    pub(crate) raw: RawTable<T, A>,
}

impl<T> HashTable<T, Global> {
    /// Creates an empty `HashTable`.
    ///
    /// The hash table is initially created with a capacity of 0, so it will not allocate until it
    /// is first inserted into.
    ///
    /// # Examples
    ///
    /// ```
    /// use hashbrown::HashTable;
    /// let mut table: HashTable<&str> = HashTable::new();
    /// assert_eq!(table.len(), 0);
    /// assert_eq!(table.capacity(), 0);
    /// ```
    pub const fn new() -> Self {
        Self {
            raw: RawTable::new(),
        }
    }

    /// Creates an empty `HashTable` with the specified capacity.
    ///
    /// The hash table will be able to hold at least `capacity` elements without
    /// reallocating. If `capacity` is 0, the hash table will not allocate.
    ///
    /// # Examples
    ///
    /// ```
    /// use hashbrown::HashTable;
    /// let mut table: HashTable<&str> = HashTable::with_capacity(10);
    /// assert_eq!(table.len(), 0);
    /// assert!(table.capacity() >= 10);
    /// ```
    pub fn with_capacity(capacity: usize) -> Self {
        Self {
            raw: RawTable::with_capacity(capacity),
        }
    }
}

impl<T, A> HashTable<T, A>
where
    A: Allocator,
{
    /// Creates an empty `HashTable` using the given allocator.
    ///
    /// The hash table is initially created with a capacity of 0, so it will not allocate until it
    /// is first inserted into.
    ///
    /// # Examples
    ///
    /// ```
    /// # #[cfg(feature = "nightly")]
    /// # fn test() {
    /// use ahash::AHasher;
    /// use bumpalo::Bump;
    /// use hashbrown::HashTable;
    /// use std::hash::{BuildHasher, BuildHasherDefault};
    ///
    /// let bump = Bump::new();
    /// let mut table = HashTable::new_in(&bump);
    /// let hasher = BuildHasherDefault::<AHasher>::default();
    /// let hasher = |val: &_| hasher.hash_one(val);
    ///
    /// // The created HashTable holds none elements
    /// assert_eq!(table.len(), 0);
    ///
    /// // The created HashTable also doesn't allocate memory
    /// assert_eq!(table.capacity(), 0);
    ///
    /// // Now we insert element inside created HashTable
    /// table.insert_unique(hasher(&"One"), "One", hasher);
    /// // We can see that the HashTable holds 1 element
    /// assert_eq!(table.len(), 1);
    /// // And it also allocates some capacity
    /// assert!(table.capacity() > 1);
    /// # }
    /// # fn main() {
    /// #     #[cfg(feature = "nightly")]
    /// #     test()
    /// # }
    /// ```
    pub const fn new_in(alloc: A) -> Self {
        Self {
            raw: RawTable::new_in(alloc),
        }
    }

    /// Creates an empty `HashTable` with the specified capacity using the given allocator.
    ///
    /// The hash table will be able to hold at least `capacity` elements without
    /// reallocating. If `capacity` is 0, the hash table will not allocate.
    ///
    /// # Examples
    ///
    /// ```
    /// # #[cfg(feature = "nightly")]
    /// # fn test() {
    /// use ahash::AHasher;
    /// use bumpalo::Bump;
    /// use hashbrown::HashTable;
    /// use std::hash::{BuildHasher, BuildHasherDefault};
    ///
    /// let bump = Bump::new();
    /// let mut table = HashTable::with_capacity_in(5, &bump);
    /// let hasher = BuildHasherDefault::<AHasher>::default();
    /// let hasher = |val: &_| hasher.hash_one(val);
    ///
    /// // The created HashTable holds none elements
    /// assert_eq!(table.len(), 0);
    /// // But it can hold at least 5 elements without reallocating
    /// let empty_map_capacity = table.capacity();
    /// assert!(empty_map_capacity >= 5);
    ///
    /// // Now we insert some 5 elements inside created HashTable
    /// table.insert_unique(hasher(&"One"), "One", hasher);
    /// table.insert_unique(hasher(&"Two"), "Two", hasher);
    /// table.insert_unique(hasher(&"Three"), "Three", hasher);
    /// table.insert_unique(hasher(&"Four"), "Four", hasher);
    /// table.insert_unique(hasher(&"Five"), "Five", hasher);
    ///
    /// // We can see that the HashTable holds 5 elements
    /// assert_eq!(table.len(), 5);
    /// // But its capacity isn't changed
    /// assert_eq!(table.capacity(), empty_map_capacity)
    /// # }
    /// # fn main() {
    /// #     #[cfg(feature = "nightly")]
    /// #     test()
    /// # }
    /// ```
    pub fn with_capacity_in(capacity: usize, alloc: A) -> Self {
        Self {
            raw: RawTable::with_capacity_in(capacity, alloc),
        }
    }

    /// Returns a reference to the underlying allocator.
    pub fn allocator(&self) -> &A {
        self.raw.allocator()
    }

    /// Returns a reference to an entry in the table with the given hash and
    /// which satisfies the equality function passed.
    ///
    /// This method will call `eq` for all entries with the given hash, but may
    /// also call it for entries with a different hash. `eq` should only return
    /// true for the desired entry, at which point the search is stopped.
    ///
    /// # Examples
    ///
    /// ```
    /// # #[cfg(feature = "nightly")]
    /// # fn test() {
    /// use ahash::AHasher;
    /// use hashbrown::HashTable;
    /// use std::hash::{BuildHasher, BuildHasherDefault};
    ///
    /// let mut table = HashTable::new();
    /// let hasher = BuildHasherDefault::<AHasher>::default();
    /// let hasher = |val: &_| hasher.hash_one(val);
    /// table.insert_unique(hasher(&1), 1, hasher);
    /// table.insert_unique(hasher(&2), 2, hasher);
    /// table.insert_unique(hasher(&3), 3, hasher);
    /// assert_eq!(table.find(hasher(&2), |&val| val == 2), Some(&2));
    /// assert_eq!(table.find(hasher(&4), |&val| val == 4), None);
    /// # }
    /// # fn main() {
    /// #     #[cfg(feature = "nightly")]
    /// #     test()
    /// # }
    /// ```
    pub fn find(&self, hash: u64, eq: impl FnMut(&T) -> bool) -> Option<&T> {
        self.raw.get(hash, eq)
    }

    /// Returns a mutable reference to an entry in the table with the given hash
    /// and which satisfies the equality function passed.
    ///
    /// This method will call `eq` for all entries with the given hash, but may
    /// also call it for entries with a different hash. `eq` should only return
    /// true for the desired entry, at which point the search is stopped.
    ///
    /// When mutating an entry, you should ensure that it still retains the same
    /// hash value as when it was inserted, otherwise lookups of that entry may
    /// fail to find it.
    ///
    /// # Examples
    ///
    /// ```
    /// # #[cfg(feature = "nightly")]
    /// # fn test() {
    /// use ahash::AHasher;
    /// use hashbrown::HashTable;
    /// use std::hash::{BuildHasher, BuildHasherDefault};
    ///
    /// let mut table = HashTable::new();
    /// let hasher = BuildHasherDefault::<AHasher>::default();
    /// let hasher = |val: &_| hasher.hash_one(val);
    /// table.insert_unique(hasher(&1), (1, "a"), |val| hasher(&val.0));
    /// if let Some(val) = table.find_mut(hasher(&1), |val| val.0 == 1) {
    ///     val.1 = "b";
    /// }
    /// assert_eq!(table.find(hasher(&1), |val| val.0 == 1), Some(&(1, "b")));
    /// assert_eq!(table.find(hasher(&2), |val| val.0 == 2), None);
    /// # }
    /// # fn main() {
    /// #     #[cfg(feature = "nightly")]
    /// #     test()
    /// # }
    /// ```
    pub fn find_mut(&mut self, hash: u64, eq: impl FnMut(&T) -> bool) -> Option<&mut T> {
        self.raw.get_mut(hash, eq)
    }

    /// Returns an `OccupiedEntry` for an entry in the table with the given hash
    /// and which satisfies the equality function passed.
    ///
    /// This can be used to remove the entry from the table. Call
    /// [`HashTable::entry`] instead if you wish to insert an entry if the
    /// lookup fails.
    ///
    /// This method will call `eq` for all entries with the given hash, but may
    /// also call it for entries with a different hash. `eq` should only return
    /// true for the desired entry, at which point the search is stopped.
    ///
    /// # Examples
    ///
    /// ```
    /// # #[cfg(feature = "nightly")]
    /// # fn test() {
    /// use ahash::AHasher;
    /// use hashbrown::HashTable;
    /// use std::hash::{BuildHasher, BuildHasherDefault};
    ///
    /// let mut table = HashTable::new();
    /// let hasher = BuildHasherDefault::<AHasher>::default();
    /// let hasher = |val: &_| hasher.hash_one(val);
    /// table.insert_unique(hasher(&1), (1, "a"), |val| hasher(&val.0));
    /// if let Ok(entry) = table.find_entry(hasher(&1), |val| val.0 == 1) {
    ///     entry.remove();
    /// }
    /// assert_eq!(table.find(hasher(&1), |val| val.0 == 1), None);
    /// # }
    /// # fn main() {
    /// #     #[cfg(feature = "nightly")]
    /// #     test()
    /// # }
    /// ```
    #[cfg_attr(feature = "inline-more", inline)]
    pub fn find_entry(
        &mut self,
        hash: u64,
        eq: impl FnMut(&T) -> bool,
    ) -> Result<OccupiedEntry<'_, T, A>, AbsentEntry<'_, T, A>> {
        match self.raw.find(hash, eq) {
            Some(bucket) => Ok(OccupiedEntry {
                hash,
                bucket,
                table: self,
            }),
            None => Err(AbsentEntry { table: self }),
        }
    }

    /// Returns an `Entry` for an entry in the table with the given hash
    /// and which satisfies the equality function passed.
    ///
    /// This can be used to remove the entry from the table, or insert a new
    /// entry with the given hash if one doesn't already exist.
    ///
    /// This method will call `eq` for all entries with the given hash, but may
    /// also call it for entries with a different hash. `eq` should only return
    /// true for the desired entry, at which point the search is stopped.
    ///
    /// This method may grow the table in preparation for an insertion. Call
    /// [`HashTable::find_entry`] if this is undesirable.
    ///
    /// `hasher` is called if entries need to be moved or copied to a new table.
    /// This must return the same hash value that each entry was inserted with.
    ///
    /// # Examples
    ///
    /// ```
    /// # #[cfg(feature = "nightly")]
    /// # fn test() {
    /// use ahash::AHasher;
    /// use hashbrown::hash_table::Entry;
    /// use hashbrown::HashTable;
    /// use std::hash::{BuildHasher, BuildHasherDefault};
    ///
    /// let mut table = HashTable::new();
    /// let hasher = BuildHasherDefault::<AHasher>::default();
    /// let hasher = |val: &_| hasher.hash_one(val);
    /// table.insert_unique(hasher(&1), (1, "a"), |val| hasher(&val.0));
    /// if let Entry::Occupied(entry) = table.entry(hasher(&1), |val| val.0 == 1, |val| hasher(&val.0))
    /// {
    ///     entry.remove();
    /// }
    /// if let Entry::Vacant(entry) = table.entry(hasher(&2), |val| val.0 == 2, |val| hasher(&val.0)) {
    ///     entry.insert((2, "b"));
    /// }
    /// assert_eq!(table.find(hasher(&1), |val| val.0 == 1), None);
    /// assert_eq!(table.find(hasher(&2), |val| val.0 == 2), Some(&(2, "b")));
    /// # }
    /// # fn main() {
    /// #     #[cfg(feature = "nightly")]
    /// #     test()
    /// # }
    /// ```
    #[cfg_attr(feature = "inline-more", inline)]
    pub fn entry(
        &mut self,
        hash: u64,
        eq: impl FnMut(&T) -> bool,
        hasher: impl Fn(&T) -> u64,
    ) -> Entry<'_, T, A> {
        match self.raw.find_or_find_insert_slot(hash, eq, hasher) {
            Ok(bucket) => Entry::Occupied(OccupiedEntry {
                hash,
                bucket,
                table: self,
            }),
            Err(insert_slot) => Entry::Vacant(VacantEntry {
                hash,
                insert_slot,
                table: self,
            }),
        }
    }

    /// Inserts an element into the `HashTable` with the given hash value, but
    /// without checking whether an equivalent element already exists within the
    /// table.
    ///
    /// `hasher` is called if entries need to be moved or copied to a new table.
    /// This must return the same hash value that each entry was inserted with.
    ///
    /// # Examples
    ///
    /// ```
    /// # #[cfg(feature = "nightly")]
    /// # fn test() {
    /// use ahash::AHasher;
    /// use hashbrown::HashTable;
    /// use std::hash::{BuildHasher, BuildHasherDefault};
    ///
    /// let mut v = HashTable::new();
    /// let hasher = BuildHasherDefault::<AHasher>::default();
    /// let hasher = |val: &_| hasher.hash_one(val);
    /// v.insert_unique(hasher(&1), 1, hasher);
    /// # }
    /// # fn main() {
    /// #     #[cfg(feature = "nightly")]
    /// #     test()
    /// # }
    /// ```
    pub fn insert_unique(
        &mut self,
        hash: u64,
        value: T,
        hasher: impl Fn(&T) -> u64,
    ) -> OccupiedEntry<'_, T, A> {
        let bucket = self.raw.insert(hash, value, hasher);
        OccupiedEntry {
            hash,
            bucket,
            table: self,
        }
    }

    /// Clears the table, removing all values.
    ///
    /// # Examples
    ///
    /// ```
    /// # #[cfg(feature = "nightly")]
    /// # fn test() {
    /// use ahash::AHasher;
    /// use hashbrown::HashTable;
    /// use std::hash::{BuildHasher, BuildHasherDefault};
    ///
    /// let mut v = HashTable::new();
    /// let hasher = BuildHasherDefault::<AHasher>::default();
    /// let hasher = |val: &_| hasher.hash_one(val);
    /// v.insert_unique(hasher(&1), 1, hasher);
    /// v.clear();
    /// assert!(v.is_empty());
    /// # }
    /// # fn main() {
    /// #     #[cfg(feature = "nightly")]
    /// #     test()
    /// # }
    /// ```
    pub fn clear(&mut self) {
        self.raw.clear();
    }

    /// Shrinks the capacity of the table as much as possible. It will drop
    /// down as much as possible while maintaining the internal rules
    /// and possibly leaving some space in accordance with the resize policy.
    ///
    /// `hasher` is called if entries need to be moved or copied to a new table.
    /// This must return the same hash value that each entry was inserted with.
    ///
    /// # Examples
    ///
    /// ```
    /// # #[cfg(feature = "nightly")]
    /// # fn test() {
    /// use ahash::AHasher;
    /// use hashbrown::HashTable;
    /// use std::hash::{BuildHasher, BuildHasherDefault};
    ///
    /// let mut table = HashTable::with_capacity(100);
    /// let hasher = BuildHasherDefault::<AHasher>::default();
    /// let hasher = |val: &_| hasher.hash_one(val);
    /// table.insert_unique(hasher(&1), 1, hasher);
    /// table.insert_unique(hasher(&2), 2, hasher);
    /// assert!(table.capacity() >= 100);
    /// table.shrink_to_fit(hasher);
    /// assert!(table.capacity() >= 2);
    /// # }
    /// # fn main() {
    /// #     #[cfg(feature = "nightly")]
    /// #     test()
    /// # }
    /// ```
    pub fn shrink_to_fit(&mut self, hasher: impl Fn(&T) -> u64) {
        self.raw.shrink_to(self.len(), hasher)
    }

    /// Shrinks the capacity of the table with a lower limit. It will drop
    /// down no lower than the supplied limit while maintaining the internal rules
    /// and possibly leaving some space in accordance with the resize policy.
    ///
    /// `hasher` is called if entries need to be moved or copied to a new table.
    /// This must return the same hash value that each entry was inserted with.
    ///
    /// Panics if the current capacity is smaller than the supplied
    /// minimum capacity.
    ///
    /// # Examples
    ///
    /// ```
    /// # #[cfg(feature = "nightly")]
    /// # fn test() {
    /// use ahash::AHasher;
    /// use hashbrown::HashTable;
    /// use std::hash::{BuildHasher, BuildHasherDefault};
    ///
    /// let mut table = HashTable::with_capacity(100);
    /// let hasher = BuildHasherDefault::<AHasher>::default();
    /// let hasher = |val: &_| hasher.hash_one(val);
    /// table.insert_unique(hasher(&1), 1, hasher);
    /// table.insert_unique(hasher(&2), 2, hasher);
    /// assert!(table.capacity() >= 100);
    /// table.shrink_to(10, hasher);
    /// assert!(table.capacity() >= 10);
    /// table.shrink_to(0, hasher);
    /// assert!(table.capacity() >= 2);
    /// # }
    /// # fn main() {
    /// #     #[cfg(feature = "nightly")]
    /// #     test()
    /// # }
    /// ```
    pub fn shrink_to(&mut self, min_capacity: usize, hasher: impl Fn(&T) -> u64) {
        self.raw.shrink_to(min_capacity, hasher);
    }

    /// Reserves capacity for at least `additional` more elements to be inserted
    /// in the `HashTable`. The collection may reserve more space to avoid
    /// frequent reallocations.
    ///
    /// `hasher` is called if entries need to be moved or copied to a new table.
    /// This must return the same hash value that each entry was inserted with.
    ///
    /// # Panics
    ///
    /// Panics if the new capacity exceeds [`isize::MAX`] bytes and [`abort`] the program
    /// in case of allocation error. Use [`try_reserve`](HashTable::try_reserve) instead
    /// if you want to handle memory allocation failure.
    ///
    /// [`isize::MAX`]: https://doc.rust-lang.org/std/primitive.isize.html
    /// [`abort`]: https://doc.rust-lang.org/alloc/alloc/fn.handle_alloc_error.html
    ///
    /// # Examples
    ///
    /// ```
    /// # #[cfg(feature = "nightly")]
    /// # fn test() {
    /// use ahash::AHasher;
    /// use hashbrown::HashTable;
    /// use std::hash::{BuildHasher, BuildHasherDefault};
    ///
    /// let mut table: HashTable<i32> = HashTable::new();
    /// let hasher = BuildHasherDefault::<AHasher>::default();
    /// let hasher = |val: &_| hasher.hash_one(val);
    /// table.reserve(10, hasher);
    /// assert!(table.capacity() >= 10);
    /// # }
    /// # fn main() {
    /// #     #[cfg(feature = "nightly")]
    /// #     test()
    /// # }
    /// ```
    pub fn reserve(&mut self, additional: usize, hasher: impl Fn(&T) -> u64) {
        self.raw.reserve(additional, hasher)
    }

    /// Tries to reserve capacity for at least `additional` more elements to be inserted
    /// in the given `HashTable`. The collection may reserve more space to avoid
    /// frequent reallocations.
    ///
    /// `hasher` is called if entries need to be moved or copied to a new table.
    /// This must return the same hash value that each entry was inserted with.
    ///
    /// # Errors
    ///
    /// If the capacity overflows, or the allocator reports a failure, then an error
    /// is returned.
    ///
    /// # Examples
    ///
    /// ```
    /// # #[cfg(feature = "nightly")]
    /// # fn test() {
    /// use ahash::AHasher;
    /// use hashbrown::HashTable;
    /// use std::hash::{BuildHasher, BuildHasherDefault};
    ///
    /// let mut table: HashTable<i32> = HashTable::new();
    /// let hasher = BuildHasherDefault::<AHasher>::default();
    /// let hasher = |val: &_| hasher.hash_one(val);
    /// table
    ///     .try_reserve(10, hasher)
    ///     .expect("why is the test harness OOMing on 10 bytes?");
    /// # }
    /// # fn main() {
    /// #     #[cfg(feature = "nightly")]
    /// #     test()
    /// # }
    /// ```
    pub fn try_reserve(
        &mut self,
        additional: usize,
        hasher: impl Fn(&T) -> u64,
    ) -> Result<(), TryReserveError> {
        self.raw.try_reserve(additional, hasher)
    }

    /// Returns the number of elements the table can hold without reallocating.
    ///
    /// # Examples
    ///
    /// ```
    /// use hashbrown::HashTable;
    /// let table: HashTable<i32> = HashTable::with_capacity(100);
    /// assert!(table.capacity() >= 100);
    /// ```
    pub fn capacity(&self) -> usize {
        self.raw.capacity()
    }

    /// Returns the number of elements in the table.
    ///
    /// # Examples
    ///
    /// ```
    /// # #[cfg(feature = "nightly")]
    /// # fn test() {
    /// use ahash::AHasher;
    /// use hashbrown::HashTable;
    /// use std::hash::{BuildHasher, BuildHasherDefault};
    ///
    /// let hasher = BuildHasherDefault::<AHasher>::default();
    /// let hasher = |val: &_| hasher.hash_one(val);
    /// let mut v = HashTable::new();
    /// assert_eq!(v.len(), 0);
    /// v.insert_unique(hasher(&1), 1, hasher);
    /// assert_eq!(v.len(), 1);
    /// # }
    /// # fn main() {
    /// #     #[cfg(feature = "nightly")]
    /// #     test()
    /// # }
    /// ```
    pub fn len(&self) -> usize {
        self.raw.len()
    }

    /// Returns `true` if the set contains no elements.
    ///
    /// # Examples
    ///
    /// ```
    /// # #[cfg(feature = "nightly")]
    /// # fn test() {
    /// use ahash::AHasher;
    /// use hashbrown::HashTable;
    /// use std::hash::{BuildHasher, BuildHasherDefault};
    ///
    /// let hasher = BuildHasherDefault::<AHasher>::default();
    /// let hasher = |val: &_| hasher.hash_one(val);
    /// let mut v = HashTable::new();
    /// assert!(v.is_empty());
    /// v.insert_unique(hasher(&1), 1, hasher);
    /// assert!(!v.is_empty());
    /// # }
    /// # fn main() {
    /// #     #[cfg(feature = "nightly")]
    /// #     test()
    /// # }
    /// ```
    pub fn is_empty(&self) -> bool {
        self.raw.is_empty()
    }

    /// An iterator visiting all elements in arbitrary order.
    /// The iterator element type is `&'a T`.
    ///
    /// # Examples
    ///
    /// ```
    /// # #[cfg(feature = "nightly")]
    /// # fn test() {
    /// use ahash::AHasher;
    /// use hashbrown::HashTable;
    /// use std::hash::{BuildHasher, BuildHasherDefault};
    ///
    /// let mut table = HashTable::new();
    /// let hasher = BuildHasherDefault::<AHasher>::default();
    /// let hasher = |val: &_| hasher.hash_one(val);
    /// table.insert_unique(hasher(&"a"), "b", hasher);
    /// table.insert_unique(hasher(&"b"), "b", hasher);
    ///
    /// // Will print in an arbitrary order.
    /// for x in table.iter() {
    ///     println!("{}", x);
    /// }
    /// # }
    /// # fn main() {
    /// #     #[cfg(feature = "nightly")]
    /// #     test()
    /// # }
    /// ```
    pub fn iter(&self) -> Iter<'_, T> {
        Iter {
            inner: unsafe { self.raw.iter() },
            marker: PhantomData,
        }
    }

    /// An iterator visiting all elements in arbitrary order,
    /// with mutable references to the elements.
    /// The iterator element type is `&'a mut T`.
    ///
    /// # Examples
    ///
    /// ```
    /// # #[cfg(feature = "nightly")]
    /// # fn test() {
    /// use ahash::AHasher;
    /// use hashbrown::HashTable;
    /// use std::hash::{BuildHasher, BuildHasherDefault};
    ///
    /// let mut table = HashTable::new();
    /// let hasher = BuildHasherDefault::<AHasher>::default();
    /// let hasher = |val: &_| hasher.hash_one(val);
    /// table.insert_unique(hasher(&1), 1, hasher);
    /// table.insert_unique(hasher(&2), 2, hasher);
    /// table.insert_unique(hasher(&3), 3, hasher);
    ///
    /// // Update all values
    /// for val in table.iter_mut() {
    ///     *val *= 2;
    /// }
    ///
    /// assert_eq!(table.len(), 3);
    /// let mut vec: Vec<i32> = Vec::new();
    ///
    /// for val in &table {
    ///     println!("val: {}", val);
    ///     vec.push(*val);
    /// }
    ///
    /// // The `Iter` iterator produces items in arbitrary order, so the
    /// // items must be sorted to test them against a sorted array.
    /// vec.sort_unstable();
    /// assert_eq!(vec, [2, 4, 6]);
    ///
    /// assert_eq!(table.len(), 3);
    /// # }
    /// # fn main() {
    /// #     #[cfg(feature = "nightly")]
    /// #     test()
    /// # }
    /// ```
    pub fn iter_mut(&mut self) -> IterMut<'_, T> {
        IterMut {
            inner: unsafe { self.raw.iter() },
            marker: PhantomData,
        }
    }

    /// Retains only the elements specified by the predicate.
    ///
    /// In other words, remove all elements `e` such that `f(&e)` returns `false`.
    ///
    /// # Examples
    ///
    /// ```
    /// # #[cfg(feature = "nightly")]
    /// # fn test() {
    /// use ahash::AHasher;
    /// use hashbrown::HashTable;
    /// use std::hash::{BuildHasher, BuildHasherDefault};
    ///
    /// let mut table = HashTable::new();
    /// let hasher = BuildHasherDefault::<AHasher>::default();
    /// let hasher = |val: &_| hasher.hash_one(val);
    /// for x in 1..=6 {
    ///     table.insert_unique(hasher(&x), x, hasher);
    /// }
    /// table.retain(|&mut x| x % 2 == 0);
    /// assert_eq!(table.len(), 3);
    /// # }
    /// # fn main() {
    /// #     #[cfg(feature = "nightly")]
    /// #     test()
    /// # }
    /// ```
    pub fn retain(&mut self, mut f: impl FnMut(&mut T) -> bool) {
        // Here we only use `iter` as a temporary, preventing use-after-free
        unsafe {
            for item in self.raw.iter() {
                if !f(item.as_mut()) {
                    self.raw.erase(item);
                }
            }
        }
    }

    /// Clears the set, returning all elements in an iterator.
    ///
    /// # Examples
    ///
    /// ```
    /// # #[cfg(feature = "nightly")]
    /// # fn test() {
    /// use ahash::AHasher;
    /// use hashbrown::HashTable;
    /// use std::hash::{BuildHasher, BuildHasherDefault};
    ///
    /// let mut table = HashTable::new();
    /// let hasher = BuildHasherDefault::<AHasher>::default();
    /// let hasher = |val: &_| hasher.hash_one(val);
    /// for x in 1..=3 {
    ///     table.insert_unique(hasher(&x), x, hasher);
    /// }
    /// assert!(!table.is_empty());
    ///
    /// // print 1, 2, 3 in an arbitrary order
    /// for i in table.drain() {
    ///     println!("{}", i);
    /// }
    ///
    /// assert!(table.is_empty());
    /// # }
    /// # fn main() {
    /// #     #[cfg(feature = "nightly")]
    /// #     test()
    /// # }
    /// ```
    pub fn drain(&mut self) -> Drain<'_, T, A> {
        Drain {
            inner: self.raw.drain(),
        }
    }

    /// Drains elements which are true under the given predicate,
    /// and returns an iterator over the removed items.
    ///
    /// In other words, move all elements `e` such that `f(&e)` returns `true` out
    /// into another iterator.
    ///
    /// If the returned `ExtractIf` is not exhausted, e.g. because it is dropped without iterating
    /// or the iteration short-circuits, then the remaining elements will be retained.
    /// Use [`retain()`] with a negated predicate if you do not need the returned iterator.
    ///
    /// [`retain()`]: HashTable::retain
    ///
    /// # Examples
    ///
    /// ```
    /// # #[cfg(feature = "nightly")]
    /// # fn test() {
    /// use ahash::AHasher;
    /// use hashbrown::HashTable;
    /// use std::hash::{BuildHasher, BuildHasherDefault};
    ///
    /// let mut table = HashTable::new();
    /// let hasher = BuildHasherDefault::<AHasher>::default();
    /// let hasher = |val: &_| hasher.hash_one(val);
    /// for x in 0..8 {
    ///     table.insert_unique(hasher(&x), x, hasher);
    /// }
    /// let drained: Vec<i32> = table.extract_if(|&mut v| v % 2 == 0).collect();
    ///
    /// let mut evens = drained.into_iter().collect::<Vec<_>>();
    /// let mut odds = table.into_iter().collect::<Vec<_>>();
    /// evens.sort();
    /// odds.sort();
    ///
    /// assert_eq!(evens, vec![0, 2, 4, 6]);
    /// assert_eq!(odds, vec![1, 3, 5, 7]);
    /// # }
    /// # fn main() {
    /// #     #[cfg(feature = "nightly")]
    /// #     test()
    /// # }
    /// ```
    pub fn extract_if<F>(&mut self, f: F) -> ExtractIf<'_, T, F, A>
    where
        F: FnMut(&mut T) -> bool,
    {
        ExtractIf {
            f,
            inner: RawExtractIf {
                iter: unsafe { self.raw.iter() },
                table: &mut self.raw,
            },
        }
    }

    /// Attempts to get mutable references to `N` values in the map at once.
    ///
    /// The `eq` argument should be a closure such that `eq(i, k)` returns true if `k` is equal to
    /// the `i`th key to be looked up.
    ///
    /// Returns an array of length `N` with the results of each query. For soundness, at most one
    /// mutable reference will be returned to any value. `None` will be returned if any of the
    /// keys are duplicates or missing.
    ///
    /// # Examples
    ///
    /// ```
    /// # #[cfg(feature = "nightly")]
    /// # fn test() {
    /// use ahash::AHasher;
    /// use hashbrown::hash_table::Entry;
    /// use hashbrown::HashTable;
    /// use std::hash::{BuildHasher, BuildHasherDefault};
    ///
    /// let mut libraries: HashTable<(&str, u32)> = HashTable::new();
    /// let hasher = BuildHasherDefault::<AHasher>::default();
    /// let hasher = |val: &_| hasher.hash_one(val);
    /// for (k, v) in [
    ///     ("Bodleian Library", 1602),
    ///     ("Athenæum", 1807),
    ///     ("Herzogin-Anna-Amalia-Bibliothek", 1691),
    ///     ("Library of Congress", 1800),
    /// ] {
    ///     libraries.insert_unique(hasher(&k), (k, v), |(k, _)| hasher(&k));
    /// }
    ///
    /// let keys = ["Athenæum", "Library of Congress"];
    /// let got = libraries.get_many_mut(keys.map(|k| hasher(&k)), |i, val| keys[i] == val.0);
    /// assert_eq!(
    ///     got,
    ///     Some([&mut ("Athenæum", 1807), &mut ("Library of Congress", 1800),]),
    /// );
    ///
    /// // Missing keys result in None
    /// let keys = ["Athenæum", "New York Public Library"];
    /// let got = libraries.get_many_mut(keys.map(|k| hasher(&k)), |i, val| keys[i] == val.0);
    /// assert_eq!(got, None);
    ///
    /// // Duplicate keys result in None
    /// let keys = ["Athenæum", "Athenæum"];
    /// let got = libraries.get_many_mut(keys.map(|k| hasher(&k)), |i, val| keys[i] == val.0);
    /// assert_eq!(got, None);
    /// # }
    /// # fn main() {
    /// #     #[cfg(feature = "nightly")]
    /// #     test()
    /// # }
    /// ```
    pub fn get_many_mut<const N: usize>(
        &mut self,
        hashes: [u64; N],
        eq: impl FnMut(usize, &T) -> bool,
    ) -> Option<[&'_ mut T; N]> {
        self.raw.get_many_mut(hashes, eq)
    }

    /// Attempts to get mutable references to `N` values in the map at once, without validating that
    /// the values are unique.
    ///
    /// The `eq` argument should be a closure such that `eq(i, k)` returns true if `k` is equal to
    /// the `i`th key to be looked up.
    ///
    /// Returns an array of length `N` with the results of each query. `None` will be returned if
    /// any of the keys are missing.
    ///
    /// For a safe alternative see [`get_many_mut`](`HashTable::get_many_mut`).
    ///
    /// # Safety
    ///
    /// Calling this method with overlapping keys is *[undefined behavior]* even if the resulting
    /// references are not used.
    ///
    /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
    ///
    /// # Examples
    ///
    /// ```
    /// # #[cfg(feature = "nightly")]
    /// # fn test() {
    /// use ahash::AHasher;
    /// use hashbrown::hash_table::Entry;
    /// use hashbrown::HashTable;
    /// use std::hash::{BuildHasher, BuildHasherDefault};
    ///
    /// let mut libraries: HashTable<(&str, u32)> = HashTable::new();
    /// let hasher = BuildHasherDefault::<AHasher>::default();
    /// let hasher = |val: &_| hasher.hash_one(val);
    /// for (k, v) in [
    ///     ("Bodleian Library", 1602),
    ///     ("Athenæum", 1807),
    ///     ("Herzogin-Anna-Amalia-Bibliothek", 1691),
    ///     ("Library of Congress", 1800),
    /// ] {
    ///     libraries.insert_unique(hasher(&k), (k, v), |(k, _)| hasher(&k));
    /// }
    ///
    /// let keys = ["Athenæum", "Library of Congress"];
    /// let got = libraries.get_many_mut(keys.map(|k| hasher(&k)), |i, val| keys[i] == val.0);
    /// assert_eq!(
    ///     got,
    ///     Some([&mut ("Athenæum", 1807), &mut ("Library of Congress", 1800),]),
    /// );
    ///
    /// // Missing keys result in None
    /// let keys = ["Athenæum", "New York Public Library"];
    /// let got = libraries.get_many_mut(keys.map(|k| hasher(&k)), |i, val| keys[i] == val.0);
    /// assert_eq!(got, None);
    ///
    /// // Duplicate keys result in None
    /// let keys = ["Athenæum", "Athenæum"];
    /// let got = libraries.get_many_mut(keys.map(|k| hasher(&k)), |i, val| keys[i] == val.0);
    /// assert_eq!(got, None);
    /// # }
    /// # fn main() {
    /// #     #[cfg(feature = "nightly")]
    /// #     test()
    /// # }
    /// ```
    pub unsafe fn get_many_unchecked_mut<const N: usize>(
        &mut self,
        hashes: [u64; N],
        eq: impl FnMut(usize, &T) -> bool,
    ) -> Option<[&'_ mut T; N]> {
        self.raw.get_many_unchecked_mut(hashes, eq)
    }
}

impl<T, A> IntoIterator for HashTable<T, A>
where
    A: Allocator,
{
    type Item = T;
    type IntoIter = IntoIter<T, A>;

    fn into_iter(self) -> IntoIter<T, A> {
        IntoIter {
            inner: self.raw.into_iter(),
        }
    }
}

impl<'a, T, A> IntoIterator for &'a HashTable<T, A>
where
    A: Allocator,
{
    type Item = &'a T;
    type IntoIter = Iter<'a, T>;

    fn into_iter(self) -> Iter<'a, T> {
        self.iter()
    }
}

impl<'a, T, A> IntoIterator for &'a mut HashTable<T, A>
where
    A: Allocator,
{
    type Item = &'a mut T;
    type IntoIter = IterMut<'a, T>;

    fn into_iter(self) -> IterMut<'a, T> {
        self.iter_mut()
    }
}

impl<T, A> Default for HashTable<T, A>
where
    A: Allocator + Default,
{
    fn default() -> Self {
        Self {
            raw: Default::default(),
        }
    }
}

impl<T, A> Clone for HashTable<T, A>
where
    T: Clone,
    A: Allocator + Clone,
{
    fn clone(&self) -> Self {
        Self {
            raw: self.raw.clone(),
        }
    }
}

impl<T, A> fmt::Debug for HashTable<T, A>
where
    T: fmt::Debug,
    A: Allocator,
{
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_set().entries(self.iter()).finish()
    }
}

/// A view into a single entry in a table, which may either be vacant or occupied.
///
/// This `enum` is constructed from the [`entry`] method on [`HashTable`].
///
/// [`HashTable`]: struct.HashTable.html
/// [`entry`]: struct.HashTable.html#method.entry
///
/// # Examples
///
/// ```
/// # #[cfg(feature = "nightly")]
/// # fn test() {
/// use ahash::AHasher;
/// use hashbrown::hash_table::{Entry, HashTable, OccupiedEntry};
/// use std::hash::{BuildHasher, BuildHasherDefault};
///
/// let mut table = HashTable::new();
/// let hasher = BuildHasherDefault::<AHasher>::default();
/// let hasher = |val: &_| hasher.hash_one(val);
/// for x in ["a", "b", "c"] {
///     table.insert_unique(hasher(&x), x, hasher);
/// }
/// assert_eq!(table.len(), 3);
///
/// // Existing value (insert)
/// let entry: Entry<_> = table.entry(hasher(&"a"), |&x| x == "a", hasher);
/// let _raw_o: OccupiedEntry<_, _> = entry.insert("a");
/// assert_eq!(table.len(), 3);
/// // Nonexistent value (insert)
/// table.entry(hasher(&"d"), |&x| x == "d", hasher).insert("d");
///
/// // Existing value (or_insert)
/// table
///     .entry(hasher(&"b"), |&x| x == "b", hasher)
///     .or_insert("b");
/// // Nonexistent value (or_insert)
/// table
///     .entry(hasher(&"e"), |&x| x == "e", hasher)
///     .or_insert("e");
///
/// println!("Our HashTable: {:?}", table);
///
/// let mut vec: Vec<_> = table.iter().copied().collect();
/// // The `Iter` iterator produces items in arbitrary order, so the
/// // items must be sorted to test them against a sorted array.
/// vec.sort_unstable();
/// assert_eq!(vec, ["a", "b", "c", "d", "e"]);
/// # }
/// # fn main() {
/// #     #[cfg(feature = "nightly")]
/// #     test()
/// # }
/// ```
pub enum Entry<'a, T, A = Global>
where
    A: Allocator,
{
    /// An occupied entry.
    ///
    /// # Examples
    ///
    /// ```
    /// # #[cfg(feature = "nightly")]
    /// # fn test() {
    /// use ahash::AHasher;
    /// use hashbrown::hash_table::{Entry, HashTable, OccupiedEntry};
    /// use std::hash::{BuildHasher, BuildHasherDefault};
    ///
    /// let mut table = HashTable::new();
    /// let hasher = BuildHasherDefault::<AHasher>::default();
    /// let hasher = |val: &_| hasher.hash_one(val);
    /// for x in ["a", "b"] {
    ///     table.insert_unique(hasher(&x), x, hasher);
    /// }
    ///
    /// match table.entry(hasher(&"a"), |&x| x == "a", hasher) {
    ///     Entry::Vacant(_) => unreachable!(),
    ///     Entry::Occupied(_) => {}
    /// }
    /// # }
    /// # fn main() {
    /// #     #[cfg(feature = "nightly")]
    /// #     test()
    /// # }
    /// ```
    Occupied(OccupiedEntry<'a, T, A>),

    /// A vacant entry.
    ///
    /// # Examples
    ///
    /// ```
    /// # #[cfg(feature = "nightly")]
    /// # fn test() {
    /// use ahash::AHasher;
    /// use hashbrown::hash_table::{Entry, HashTable, OccupiedEntry};
    /// use std::hash::{BuildHasher, BuildHasherDefault};
    ///
    /// let mut table = HashTable::<&str>::new();
    /// let hasher = BuildHasherDefault::<AHasher>::default();
    /// let hasher = |val: &_| hasher.hash_one(val);
    ///
    /// match table.entry(hasher(&"a"), |&x| x == "a", hasher) {
    ///     Entry::Vacant(_) => {}
    ///     Entry::Occupied(_) => unreachable!(),
    /// }
    /// # }
    /// # fn main() {
    /// #     #[cfg(feature = "nightly")]
    /// #     test()
    /// # }
    /// ```
    Vacant(VacantEntry<'a, T, A>),
}

impl<T: fmt::Debug, A: Allocator> fmt::Debug for Entry<'_, T, A> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match *self {
            Entry::Vacant(ref v) => f.debug_tuple("Entry").field(v).finish(),
            Entry::Occupied(ref o) => f.debug_tuple("Entry").field(o).finish(),
        }
    }
}

impl<'a, T, A> Entry<'a, T, A>
where
    A: Allocator,
{
    /// Sets the value of the entry, replacing any existing value if there is
    /// one, and returns an [`OccupiedEntry`].
    ///
    /// # Examples
    ///
    /// ```
    /// # #[cfg(feature = "nightly")]
    /// # fn test() {
    /// use ahash::AHasher;
    /// use hashbrown::HashTable;
    /// use std::hash::{BuildHasher, BuildHasherDefault};
    ///
    /// let mut table: HashTable<&str> = HashTable::new();
    /// let hasher = BuildHasherDefault::<AHasher>::default();
    /// let hasher = |val: &_| hasher.hash_one(val);
    ///
    /// let entry = table
    ///     .entry(hasher(&"horseyland"), |&x| x == "horseyland", hasher)
    ///     .insert("horseyland");
    ///
    /// assert_eq!(entry.get(), &"horseyland");
    /// # }
    /// # fn main() {
    /// #     #[cfg(feature = "nightly")]
    /// #     test()
    /// # }
    /// ```
    pub fn insert(self, value: T) -> OccupiedEntry<'a, T, A> {
        match self {
            Entry::Occupied(mut entry) => {
                *entry.get_mut() = value;
                entry
            }
            Entry::Vacant(entry) => entry.insert(value),
        }
    }

    /// Ensures a value is in the entry by inserting if it was vacant.
    ///
    /// Returns an [`OccupiedEntry`] pointing to the now-occupied entry.
    ///
    /// # Examples
    ///
    /// ```
    /// # #[cfg(feature = "nightly")]
    /// # fn test() {
    /// use ahash::AHasher;
    /// use hashbrown::HashTable;
    /// use std::hash::{BuildHasher, BuildHasherDefault};
    ///
    /// let mut table: HashTable<&str> = HashTable::new();
    /// let hasher = BuildHasherDefault::<AHasher>::default();
    /// let hasher = |val: &_| hasher.hash_one(val);
    ///
    /// // nonexistent key
    /// table
    ///     .entry(hasher(&"poneyland"), |&x| x == "poneyland", hasher)
    ///     .or_insert("poneyland");
    /// assert!(table
    ///     .find(hasher(&"poneyland"), |&x| x == "poneyland")
    ///     .is_some());
    ///
    /// // existing key
    /// table
    ///     .entry(hasher(&"poneyland"), |&x| x == "poneyland", hasher)
    ///     .or_insert("poneyland");
    /// assert!(table
    ///     .find(hasher(&"poneyland"), |&x| x == "poneyland")
    ///     .is_some());
    /// assert_eq!(table.len(), 1);
    /// # }
    /// # fn main() {
    /// #     #[cfg(feature = "nightly")]
    /// #     test()
    /// # }
    /// ```
    pub fn or_insert(self, default: T) -> OccupiedEntry<'a, T, A> {
        match self {
            Entry::Occupied(entry) => entry,
            Entry::Vacant(entry) => entry.insert(default),
        }
    }

    /// Ensures a value is in the entry by inserting the result of the default function if empty..
    ///
    /// Returns an [`OccupiedEntry`] pointing to the now-occupied entry.
    ///
    /// # Examples
    ///
    /// ```
    /// # #[cfg(feature = "nightly")]
    /// # fn test() {
    /// use ahash::AHasher;
    /// use hashbrown::HashTable;
    /// use std::hash::{BuildHasher, BuildHasherDefault};
    ///
    /// let mut table: HashTable<String> = HashTable::new();
    /// let hasher = BuildHasherDefault::<AHasher>::default();
    /// let hasher = |val: &_| hasher.hash_one(val);
    ///
    /// table
    ///     .entry(hasher("poneyland"), |x| x == "poneyland", |val| hasher(val))
    ///     .or_insert_with(|| "poneyland".to_string());
    ///
    /// assert!(table
    ///     .find(hasher(&"poneyland"), |x| x == "poneyland")
    ///     .is_some());
    /// # }
    /// # fn main() {
    /// #     #[cfg(feature = "nightly")]
    /// #     test()
    /// # }
    /// ```
    pub fn or_insert_with(self, default: impl FnOnce() -> T) -> OccupiedEntry<'a, T, A> {
        match self {
            Entry::Occupied(entry) => entry,
            Entry::Vacant(entry) => entry.insert(default()),
        }
    }

    /// Provides in-place mutable access to an occupied entry before any
    /// potential inserts into the table.
    ///
    /// # Examples
    ///
    /// ```
    /// # #[cfg(feature = "nightly")]
    /// # fn test() {
    /// use ahash::AHasher;
    /// use hashbrown::HashTable;
    /// use std::hash::{BuildHasher, BuildHasherDefault};
    ///
    /// let mut table: HashTable<(&str, u32)> = HashTable::new();
    /// let hasher = BuildHasherDefault::<AHasher>::default();
    /// let hasher = |val: &_| hasher.hash_one(val);
    ///
    /// table
    ///     .entry(
    ///         hasher(&"poneyland"),
    ///         |&(x, _)| x == "poneyland",
    ///         |(k, _)| hasher(&k),
    ///     )
    ///     .and_modify(|(_, v)| *v += 1)
    ///     .or_insert(("poneyland", 42));
    /// assert_eq!(
    ///     table.find(hasher(&"poneyland"), |&(k, _)| k == "poneyland"),
    ///     Some(&("poneyland", 42))
    /// );
    ///
    /// table
    ///     .entry(
    ///         hasher(&"poneyland"),
    ///         |&(x, _)| x == "poneyland",
    ///         |(k, _)| hasher(&k),
    ///     )
    ///     .and_modify(|(_, v)| *v += 1)
    ///     .or_insert(("poneyland", 42));
    /// assert_eq!(
    ///     table.find(hasher(&"poneyland"), |&(k, _)| k == "poneyland"),
    ///     Some(&("poneyland", 43))
    /// );
    /// # }
    /// # fn main() {
    /// #     #[cfg(feature = "nightly")]
    /// #     test()
    /// # }
    /// ```
    pub fn and_modify(self, f: impl FnOnce(&mut T)) -> Self {
        match self {
            Entry::Occupied(mut entry) => {
                f(entry.get_mut());
                Entry::Occupied(entry)
            }
            Entry::Vacant(entry) => Entry::Vacant(entry),
        }
    }
}

/// A view into an occupied entry in a `HashTable`.
/// It is part of the [`Entry`] enum.
///
/// [`Entry`]: enum.Entry.html
///
/// # Examples
///
/// ```
/// # #[cfg(feature = "nightly")]
/// # fn test() {
/// use ahash::AHasher;
/// use hashbrown::hash_table::{Entry, HashTable, OccupiedEntry};
/// use std::hash::{BuildHasher, BuildHasherDefault};
///
/// let mut table = HashTable::new();
/// let hasher = BuildHasherDefault::<AHasher>::default();
/// let hasher = |val: &_| hasher.hash_one(val);
/// for x in ["a", "b", "c"] {
///     table.insert_unique(hasher(&x), x, hasher);
/// }
/// assert_eq!(table.len(), 3);
///
/// let _entry_o: OccupiedEntry<_, _> = table.find_entry(hasher(&"a"), |&x| x == "a").unwrap();
/// assert_eq!(table.len(), 3);
///
/// // Existing key
/// match table.entry(hasher(&"a"), |&x| x == "a", hasher) {
///     Entry::Vacant(_) => unreachable!(),
///     Entry::Occupied(view) => {
///         assert_eq!(view.get(), &"a");
///     }
/// }
///
/// assert_eq!(table.len(), 3);
///
/// // Existing key (take)
/// match table.entry(hasher(&"c"), |&x| x == "c", hasher) {
///     Entry::Vacant(_) => unreachable!(),
///     Entry::Occupied(view) => {
///         assert_eq!(view.remove().0, "c");
///     }
/// }
/// assert_eq!(table.find(hasher(&"c"), |&x| x == "c"), None);
/// assert_eq!(table.len(), 2);
/// # }
/// # fn main() {
/// #     #[cfg(feature = "nightly")]
/// #     test()
/// # }
/// ```
pub struct OccupiedEntry<'a, T, A = Global>
where
    A: Allocator,
{
    hash: u64,
    bucket: Bucket<T>,
    table: &'a mut HashTable<T, A>,
}

unsafe impl<T, A> Send for OccupiedEntry<'_, T, A>
where
    T: Send,
    A: Send + Allocator,
{
}
unsafe impl<T, A> Sync for OccupiedEntry<'_, T, A>
where
    T: Sync,
    A: Sync + Allocator,
{
}

impl<T: fmt::Debug, A: Allocator> fmt::Debug for OccupiedEntry<'_, T, A> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_struct("OccupiedEntry")
            .field("value", self.get())
            .finish()
    }
}

impl<'a, T, A> OccupiedEntry<'a, T, A>
where
    A: Allocator,
{
    /// Takes the value out of the entry, and returns it along with a
    /// `VacantEntry` that can be used to insert another value with the same
    /// hash as the one that was just removed.
    ///
    /// # Examples
    ///
    /// ```
    /// # #[cfg(feature = "nightly")]
    /// # fn test() {
    /// use ahash::AHasher;
    /// use hashbrown::hash_table::Entry;
    /// use hashbrown::HashTable;
    /// use std::hash::{BuildHasher, BuildHasherDefault};
    ///
    /// let mut table: HashTable<&str> = HashTable::new();
    /// let hasher = BuildHasherDefault::<AHasher>::default();
    /// let hasher = |val: &_| hasher.hash_one(val);
    /// // The table is empty
    /// assert!(table.is_empty() && table.capacity() == 0);
    ///
    /// table.insert_unique(hasher(&"poneyland"), "poneyland", hasher);
    /// let capacity_before_remove = table.capacity();
    ///
    /// if let Entry::Occupied(o) = table.entry(hasher(&"poneyland"), |&x| x == "poneyland", hasher) {
    ///     assert_eq!(o.remove().0, "poneyland");
    /// }
    ///
    /// assert!(table
    ///     .find(hasher(&"poneyland"), |&x| x == "poneyland")
    ///     .is_none());
    /// // Now table hold none elements but capacity is equal to the old one
    /// assert!(table.len() == 0 && table.capacity() == capacity_before_remove);
    /// # }
    /// # fn main() {
    /// #     #[cfg(feature = "nightly")]
    /// #     test()
    /// # }
    /// ```
    #[cfg_attr(feature = "inline-more", inline)]
    pub fn remove(self) -> (T, VacantEntry<'a, T, A>) {
        let (val, slot) = unsafe { self.table.raw.remove(self.bucket) };
        (
            val,
            VacantEntry {
                hash: self.hash,
                insert_slot: slot,
                table: self.table,
            },
        )
    }

    /// Gets a reference to the value in the entry.
    ///
    /// # Examples
    ///
    /// ```
    /// # #[cfg(feature = "nightly")]
    /// # fn test() {
    /// use ahash::AHasher;
    /// use hashbrown::hash_table::Entry;
    /// use hashbrown::HashTable;
    /// use std::hash::{BuildHasher, BuildHasherDefault};
    ///
    /// let mut table: HashTable<&str> = HashTable::new();
    /// let hasher = BuildHasherDefault::<AHasher>::default();
    /// let hasher = |val: &_| hasher.hash_one(val);
    /// table.insert_unique(hasher(&"poneyland"), "poneyland", hasher);
    ///
    /// match table.entry(hasher(&"poneyland"), |&x| x == "poneyland", hasher) {
    ///     Entry::Vacant(_) => panic!(),
    ///     Entry::Occupied(entry) => assert_eq!(entry.get(), &"poneyland"),
    /// }
    /// # }
    /// # fn main() {
    /// #     #[cfg(feature = "nightly")]
    /// #     test()
    /// # }
    /// ```
    #[inline]
    pub fn get(&self) -> &T {
        unsafe { self.bucket.as_ref() }
    }

    /// Gets a mutable reference to the value in the entry.
    ///
    /// If you need a reference to the `OccupiedEntry` which may outlive the
    /// destruction of the `Entry` value, see [`into_mut`].
    ///
    /// [`into_mut`]: #method.into_mut
    ///
    /// # Examples
    ///
    /// ```
    /// # #[cfg(feature = "nightly")]
    /// # fn test() {
    /// use ahash::AHasher;
    /// use hashbrown::hash_table::Entry;
    /// use hashbrown::HashTable;
    /// use std::hash::{BuildHasher, BuildHasherDefault};
    ///
    /// let mut table: HashTable<(&str, u32)> = HashTable::new();
    /// let hasher = BuildHasherDefault::<AHasher>::default();
    /// let hasher = |val: &_| hasher.hash_one(val);
    /// table.insert_unique(hasher(&"poneyland"), ("poneyland", 12), |(k, _)| hasher(&k));
    ///
    /// assert_eq!(
    ///     table.find(hasher(&"poneyland"), |&(x, _)| x == "poneyland",),
    ///     Some(&("poneyland", 12))
    /// );
    ///
    /// if let Entry::Occupied(mut o) = table.entry(
    ///     hasher(&"poneyland"),
    ///     |&(x, _)| x == "poneyland",
    ///     |(k, _)| hasher(&k),
    /// ) {
    ///     o.get_mut().1 += 10;
    ///     assert_eq!(o.get().1, 22);
    ///
    ///     // We can use the same Entry multiple times.
    ///     o.get_mut().1 += 2;
    /// }
    ///
    /// assert_eq!(
    ///     table.find(hasher(&"poneyland"), |&(x, _)| x == "poneyland",),
    ///     Some(&("poneyland", 24))
    /// );
    /// # }
    /// # fn main() {
    /// #     #[cfg(feature = "nightly")]
    /// #     test()
    /// # }
    /// ```
    #[inline]
    pub fn get_mut(&mut self) -> &mut T {
        unsafe { self.bucket.as_mut() }
    }

    /// Converts the OccupiedEntry into a mutable reference to the value in the entry
    /// with a lifetime bound to the table itself.
    ///
    /// If you need multiple references to the `OccupiedEntry`, see [`get_mut`].
    ///
    /// [`get_mut`]: #method.get_mut
    ///
    /// # Examples
    ///
    /// ```
    /// # #[cfg(feature = "nightly")]
    /// # fn test() {
    /// use ahash::AHasher;
    /// use hashbrown::hash_table::Entry;
    /// use hashbrown::HashTable;
    /// use std::hash::{BuildHasher, BuildHasherDefault};
    ///
    /// let mut table: HashTable<(&str, u32)> = HashTable::new();
    /// let hasher = BuildHasherDefault::<AHasher>::default();
    /// let hasher = |val: &_| hasher.hash_one(val);
    /// table.insert_unique(hasher(&"poneyland"), ("poneyland", 12), |(k, _)| hasher(&k));
    ///
    /// assert_eq!(
    ///     table.find(hasher(&"poneyland"), |&(x, _)| x == "poneyland",),
    ///     Some(&("poneyland", 12))
    /// );
    ///
    /// let value: &mut (&str, u32);
    /// match table.entry(
    ///     hasher(&"poneyland"),
    ///     |&(x, _)| x == "poneyland",
    ///     |(k, _)| hasher(&k),
    /// ) {
    ///     Entry::Occupied(entry) => value = entry.into_mut(),
    ///     Entry::Vacant(_) => panic!(),
    /// }
    /// value.1 += 10;
    ///
    /// assert_eq!(
    ///     table.find(hasher(&"poneyland"), |&(x, _)| x == "poneyland",),
    ///     Some(&("poneyland", 22))
    /// );
    /// # }
    /// # fn main() {
    /// #     #[cfg(feature = "nightly")]
    /// #     test()
    /// # }
    /// ```
    pub fn into_mut(self) -> &'a mut T {
        unsafe { self.bucket.as_mut() }
    }

    /// Converts the OccupiedEntry into a mutable reference to the underlying
    /// table.
    pub fn into_table(self) -> &'a mut HashTable<T, A> {
        self.table
    }
}

/// A view into a vacant entry in a `HashTable`.
/// It is part of the [`Entry`] enum.
///
/// [`Entry`]: enum.Entry.html
///
/// # Examples
///
/// ```
/// # #[cfg(feature = "nightly")]
/// # fn test() {
/// use ahash::AHasher;
/// use hashbrown::hash_table::{Entry, HashTable, VacantEntry};
/// use std::hash::{BuildHasher, BuildHasherDefault};
///
/// let mut table: HashTable<&str> = HashTable::new();
/// let hasher = BuildHasherDefault::<AHasher>::default();
/// let hasher = |val: &_| hasher.hash_one(val);
///
/// let entry_v: VacantEntry<_, _> = match table.entry(hasher(&"a"), |&x| x == "a", hasher) {
///     Entry::Vacant(view) => view,
///     Entry::Occupied(_) => unreachable!(),
/// };
/// entry_v.insert("a");
/// assert!(table.find(hasher(&"a"), |&x| x == "a").is_some() && table.len() == 1);
///
/// // Nonexistent key (insert)
/// match table.entry(hasher(&"b"), |&x| x == "b", hasher) {
///     Entry::Vacant(view) => {
///         view.insert("b");
///     }
///     Entry::Occupied(_) => unreachable!(),
/// }
/// assert!(table.find(hasher(&"b"), |&x| x == "b").is_some() && table.len() == 2);
/// # }
/// # fn main() {
/// #     #[cfg(feature = "nightly")]
/// #     test()
/// # }
/// ```
pub struct VacantEntry<'a, T, A = Global>
where
    A: Allocator,
{
    hash: u64,
    insert_slot: InsertSlot,
    table: &'a mut HashTable<T, A>,
}

impl<T: fmt::Debug, A: Allocator> fmt::Debug for VacantEntry<'_, T, A> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.write_str("VacantEntry")
    }
}

impl<'a, T, A> VacantEntry<'a, T, A>
where
    A: Allocator,
{
    /// Inserts a new element into the table with the hash that was used to
    /// obtain the `VacantEntry`.
    ///
    /// An `OccupiedEntry` is returned for the newly inserted element.
    ///
    /// # Examples
    ///
    /// ```
    /// # #[cfg(feature = "nightly")]
    /// # fn test() {
    /// use ahash::AHasher;
    /// use hashbrown::hash_table::Entry;
    /// use hashbrown::HashTable;
    /// use std::hash::{BuildHasher, BuildHasherDefault};
    ///
    /// let mut table: HashTable<&str> = HashTable::new();
    /// let hasher = BuildHasherDefault::<AHasher>::default();
    /// let hasher = |val: &_| hasher.hash_one(val);
    ///
    /// if let Entry::Vacant(o) = table.entry(hasher(&"poneyland"), |&x| x == "poneyland", hasher) {
    ///     o.insert("poneyland");
    /// }
    /// assert_eq!(
    ///     table.find(hasher(&"poneyland"), |&x| x == "poneyland"),
    ///     Some(&"poneyland")
    /// );
    /// # }
    /// # fn main() {
    /// #     #[cfg(feature = "nightly")]
    /// #     test()
    /// # }
    /// ```
    #[inline]
    pub fn insert(self, value: T) -> OccupiedEntry<'a, T, A> {
        let bucket = unsafe {
            self.table
                .raw
                .insert_in_slot(self.hash, self.insert_slot, value)
        };
        OccupiedEntry {
            hash: self.hash,
            bucket,
            table: self.table,
        }
    }

    /// Converts the VacantEntry into a mutable reference to the underlying
    /// table.
    pub fn into_table(self) -> &'a mut HashTable<T, A> {
        self.table
    }
}

/// Type representing the absence of an entry, as returned by [`HashTable::find_entry`].
///
/// This type only exists due to [limitations] in Rust's NLL borrow checker. In
/// the future, `find_entry` will return an `Option<OccupiedEntry>` and this
/// type will be removed.
///
/// [limitations]: https://smallcultfollowing.com/babysteps/blog/2018/06/15/mir-based-borrow-check-nll-status-update/#polonius
///
/// # Examples
///
/// ```
/// # #[cfg(feature = "nightly")]
/// # fn test() {
/// use ahash::AHasher;
/// use hashbrown::hash_table::{AbsentEntry, Entry, HashTable};
/// use std::hash::{BuildHasher, BuildHasherDefault};
///
/// let mut table: HashTable<&str> = HashTable::new();
/// let hasher = BuildHasherDefault::<AHasher>::default();
/// let hasher = |val: &_| hasher.hash_one(val);
///
/// let entry_v: AbsentEntry<_, _> = table.find_entry(hasher(&"a"), |&x| x == "a").unwrap_err();
/// entry_v
///     .into_table()
///     .insert_unique(hasher(&"a"), "a", hasher);
/// assert!(table.find(hasher(&"a"), |&x| x == "a").is_some() && table.len() == 1);
///
/// // Nonexistent key (insert)
/// match table.entry(hasher(&"b"), |&x| x == "b", hasher) {
///     Entry::Vacant(view) => {
///         view.insert("b");
///     }
///     Entry::Occupied(_) => unreachable!(),
/// }
/// assert!(table.find(hasher(&"b"), |&x| x == "b").is_some() && table.len() == 2);
/// # }
/// # fn main() {
/// #     #[cfg(feature = "nightly")]
/// #     test()
/// # }
/// ```
pub struct AbsentEntry<'a, T, A = Global>
where
    A: Allocator,
{
    table: &'a mut HashTable<T, A>,
}

impl<T: fmt::Debug, A: Allocator> fmt::Debug for AbsentEntry<'_, T, A> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.write_str("AbsentEntry")
    }
}

impl<'a, T, A> AbsentEntry<'a, T, A>
where
    A: Allocator,
{
    /// Converts the AbsentEntry into a mutable reference to the underlying
    /// table.
    pub fn into_table(self) -> &'a mut HashTable<T, A> {
        self.table
    }
}

/// An iterator over the entries of a `HashTable` in arbitrary order.
/// The iterator element type is `&'a T`.
///
/// This `struct` is created by the [`iter`] method on [`HashTable`]. See its
/// documentation for more.
///
/// [`iter`]: struct.HashTable.html#method.iter
/// [`HashTable`]: struct.HashTable.html
pub struct Iter<'a, T> {
    inner: RawIter<T>,
    marker: PhantomData<&'a T>,
}

impl<'a, T> Iterator for Iter<'a, T> {
    type Item = &'a T;

    fn next(&mut self) -> Option<Self::Item> {
        // Avoid `Option::map` because it bloats LLVM IR.
        match self.inner.next() {
            Some(bucket) => Some(unsafe { bucket.as_ref() }),
            None => None,
        }
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        self.inner.size_hint()
    }

    fn fold<B, F>(self, init: B, mut f: F) -> B
    where
        Self: Sized,
        F: FnMut(B, Self::Item) -> B,
    {
        self.inner
            .fold(init, |acc, bucket| unsafe { f(acc, bucket.as_ref()) })
    }
}

impl<T> ExactSizeIterator for Iter<'_, T> {
    fn len(&self) -> usize {
        self.inner.len()
    }
}

impl<T> FusedIterator for Iter<'_, T> {}

/// A mutable iterator over the entries of a `HashTable` in arbitrary order.
/// The iterator element type is `&'a mut T`.
///
/// This `struct` is created by the [`iter_mut`] method on [`HashTable`]. See its
/// documentation for more.
///
/// [`iter_mut`]: struct.HashTable.html#method.iter_mut
/// [`HashTable`]: struct.HashTable.html
pub struct IterMut<'a, T> {
    inner: RawIter<T>,
    marker: PhantomData<&'a mut T>,
}

impl<'a, T> Iterator for IterMut<'a, T> {
    type Item = &'a mut T;

    fn next(&mut self) -> Option<Self::Item> {
        // Avoid `Option::map` because it bloats LLVM IR.
        match self.inner.next() {
            Some(bucket) => Some(unsafe { bucket.as_mut() }),
            None => None,
        }
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        self.inner.size_hint()
    }

    fn fold<B, F>(self, init: B, mut f: F) -> B
    where
        Self: Sized,
        F: FnMut(B, Self::Item) -> B,
    {
        self.inner
            .fold(init, |acc, bucket| unsafe { f(acc, bucket.as_mut()) })
    }
}

impl<T> ExactSizeIterator for IterMut<'_, T> {
    fn len(&self) -> usize {
        self.inner.len()
    }
}

impl<T> FusedIterator for IterMut<'_, T> {}

/// An owning iterator over the entries of a `HashTable` in arbitrary order.
/// The iterator element type is `T`.
///
/// This `struct` is created by the [`into_iter`] method on [`HashTable`]
/// (provided by the [`IntoIterator`] trait). See its documentation for more.
/// The table cannot be used after calling that method.
///
/// [`into_iter`]: struct.HashTable.html#method.into_iter
/// [`HashTable`]: struct.HashTable.html
/// [`IntoIterator`]: https://doc.rust-lang.org/core/iter/trait.IntoIterator.html
pub struct IntoIter<T, A = Global>
where
    A: Allocator,
{
    inner: RawIntoIter<T, A>,
}

impl<T, A> Iterator for IntoIter<T, A>
where
    A: Allocator,
{
    type Item = T;

    fn next(&mut self) -> Option<Self::Item> {
        self.inner.next()
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        self.inner.size_hint()
    }

    fn fold<B, F>(self, init: B, f: F) -> B
    where
        Self: Sized,
        F: FnMut(B, Self::Item) -> B,
    {
        self.inner.fold(init, f)
    }
}

impl<T, A> ExactSizeIterator for IntoIter<T, A>
where
    A: Allocator,
{
    fn len(&self) -> usize {
        self.inner.len()
    }
}

impl<T, A> FusedIterator for IntoIter<T, A> where A: Allocator {}

/// A draining iterator over the items of a `HashTable`.
///
/// This `struct` is created by the [`drain`] method on [`HashTable`].
/// See its documentation for more.
///
/// [`HashTable`]: struct.HashTable.html
/// [`drain`]: struct.HashTable.html#method.drain
pub struct Drain<'a, T, A: Allocator = Global> {
    inner: RawDrain<'a, T, A>,
}

impl<T, A: Allocator> Drain<'_, T, A> {
    /// Returns a iterator of references over the remaining items.
    fn iter(&self) -> Iter<'_, T> {
        Iter {
            inner: self.inner.iter(),
            marker: PhantomData,
        }
    }
}

impl<T, A: Allocator> Iterator for Drain<'_, T, A> {
    type Item = T;

    fn next(&mut self) -> Option<T> {
        self.inner.next()
    }
    fn size_hint(&self) -> (usize, Option<usize>) {
        self.inner.size_hint()
    }
}
impl<T, A: Allocator> ExactSizeIterator for Drain<'_, T, A> {
    fn len(&self) -> usize {
        self.inner.len()
    }
}
impl<T, A: Allocator> FusedIterator for Drain<'_, T, A> {}

impl<T: fmt::Debug, A: Allocator> fmt::Debug for Drain<'_, T, A> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_list().entries(self.iter()).finish()
    }
}

/// A draining iterator over entries of a `HashTable` which don't satisfy the predicate `f`.
///
/// This `struct` is created by [`HashTable::extract_if`]. See its
/// documentation for more.
#[must_use = "Iterators are lazy unless consumed"]
pub struct ExtractIf<'a, T, F, A: Allocator = Global>
where
    F: FnMut(&mut T) -> bool,
{
    f: F,
    inner: RawExtractIf<'a, T, A>,
}

impl<T, F, A: Allocator> Iterator for ExtractIf<'_, T, F, A>
where
    F: FnMut(&mut T) -> bool,
{
    type Item = T;

    #[inline]
    fn next(&mut self) -> Option<Self::Item> {
        self.inner.next(|val| (self.f)(val))
    }

    #[inline]
    fn size_hint(&self) -> (usize, Option<usize>) {
        (0, self.inner.iter.size_hint().1)
    }
}

impl<T, F, A: Allocator> FusedIterator for ExtractIf<'_, T, F, A> where F: FnMut(&mut T) -> bool {}
