use core::{
fmt::Debug,
hash::{BuildHasher, Hash},
ops::{Deref, DerefMut, Index},
};
use hashbrown::{hash_map as hb, Equivalent};
use crate::hash::FixedHasher;
#[cfg(feature = "rayon")]
use rayon::prelude::{FromParallelIterator, IntoParallelIterator, ParallelExtend};
pub use {
crate::hash::{DefaultHasher, RandomState},
hb::{
Drain, IntoIter, IntoKeys, IntoValues, Iter, IterMut, Keys, OccupiedEntry, VacantEntry,
Values, ValuesMut,
},
};
pub use hb::{
EntryRef, ExtractIf, OccupiedError, RawEntryBuilder, RawEntryBuilderMut, RawEntryMut,
RawOccupiedEntryMut,
};
pub type Entry<'a, K, V, S = FixedHasher> = hb::Entry<'a, K, V, S>;
#[repr(transparent)]
pub struct HashMap<K, V, S = FixedHasher>(hb::HashMap<K, V, S>);
impl<K, V, S> Clone for HashMap<K, V, S>
where
hb::HashMap<K, V, S>: Clone,
{
#[inline]
fn clone(&self) -> Self {
Self(self.0.clone())
}
#[inline]
fn clone_from(&mut self, source: &Self) {
self.0.clone_from(&source.0);
}
}
impl<K, V, S> Debug for HashMap<K, V, S>
where
hb::HashMap<K, V, S>: Debug,
{
#[inline]
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
<hb::HashMap<K, V, S> as Debug>::fmt(&self.0, f)
}
}
impl<K, V, S> Default for HashMap<K, V, S>
where
hb::HashMap<K, V, S>: Default,
{
#[inline]
fn default() -> Self {
Self(Default::default())
}
}
impl<K, V, S> PartialEq for HashMap<K, V, S>
where
hb::HashMap<K, V, S>: PartialEq,
{
#[inline]
fn eq(&self, other: &Self) -> bool {
self.0.eq(&other.0)
}
}
impl<K, V, S> Eq for HashMap<K, V, S> where hb::HashMap<K, V, S>: Eq {}
impl<K, V, S, T> FromIterator<T> for HashMap<K, V, S>
where
hb::HashMap<K, V, S>: FromIterator<T>,
{
#[inline]
fn from_iter<U: IntoIterator<Item = T>>(iter: U) -> Self {
Self(FromIterator::from_iter(iter))
}
}
impl<K, V, S, T> Index<T> for HashMap<K, V, S>
where
hb::HashMap<K, V, S>: Index<T>,
{
type Output = <hb::HashMap<K, V, S> as Index<T>>::Output;
#[inline]
fn index(&self, index: T) -> &Self::Output {
self.0.index(index)
}
}
impl<K, V, S> IntoIterator for HashMap<K, V, S>
where
hb::HashMap<K, V, S>: IntoIterator,
{
type Item = <hb::HashMap<K, V, S> as IntoIterator>::Item;
type IntoIter = <hb::HashMap<K, V, S> as IntoIterator>::IntoIter;
#[inline]
fn into_iter(self) -> Self::IntoIter {
self.0.into_iter()
}
}
impl<'a, K, V, S> IntoIterator for &'a HashMap<K, V, S>
where
&'a hb::HashMap<K, V, S>: IntoIterator,
{
type Item = <&'a hb::HashMap<K, V, S> as IntoIterator>::Item;
type IntoIter = <&'a hb::HashMap<K, V, S> as IntoIterator>::IntoIter;
#[inline]
fn into_iter(self) -> Self::IntoIter {
(&self.0).into_iter()
}
}
impl<'a, K, V, S> IntoIterator for &'a mut HashMap<K, V, S>
where
&'a mut hb::HashMap<K, V, S>: IntoIterator,
{
type Item = <&'a mut hb::HashMap<K, V, S> as IntoIterator>::Item;
type IntoIter = <&'a mut hb::HashMap<K, V, S> as IntoIterator>::IntoIter;
#[inline]
fn into_iter(self) -> Self::IntoIter {
(&mut self.0).into_iter()
}
}
impl<K, V, S, T> Extend<T> for HashMap<K, V, S>
where
hb::HashMap<K, V, S>: Extend<T>,
{
#[inline]
fn extend<U: IntoIterator<Item = T>>(&mut self, iter: U) {
self.0.extend(iter);
}
}
impl<K, V, const N: usize> From<[(K, V); N]> for HashMap<K, V, FixedHasher>
where
K: Eq + Hash,
{
fn from(arr: [(K, V); N]) -> Self {
arr.into_iter().collect()
}
}
impl<K, V, S> From<hb::HashMap<K, V, S>> for HashMap<K, V, S> {
#[inline]
fn from(value: hb::HashMap<K, V, S>) -> Self {
Self(value)
}
}
impl<K, V, S> From<HashMap<K, V, S>> for hb::HashMap<K, V, S> {
#[inline]
fn from(value: HashMap<K, V, S>) -> Self {
value.0
}
}
impl<K, V, S> Deref for HashMap<K, V, S> {
type Target = hb::HashMap<K, V, S>;
#[inline]
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<K, V, S> DerefMut for HashMap<K, V, S> {
#[inline]
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
#[cfg(feature = "serialize")]
impl<K, V, S> serde::Serialize for HashMap<K, V, S>
where
hb::HashMap<K, V, S>: serde::Serialize,
{
#[inline]
fn serialize<T>(&self, serializer: T) -> Result<T::Ok, T::Error>
where
T: serde::Serializer,
{
self.0.serialize(serializer)
}
}
#[cfg(feature = "serialize")]
impl<'de, K, V, S> serde::Deserialize<'de> for HashMap<K, V, S>
where
hb::HashMap<K, V, S>: serde::Deserialize<'de>,
{
#[inline]
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
Ok(Self(serde::Deserialize::deserialize(deserializer)?))
}
}
#[cfg(feature = "rayon")]
impl<K, V, S, T> FromParallelIterator<T> for HashMap<K, V, S>
where
hb::HashMap<K, V, S>: FromParallelIterator<T>,
T: Send,
{
fn from_par_iter<P>(par_iter: P) -> Self
where
P: IntoParallelIterator<Item = T>,
{
Self(<hb::HashMap<K, V, S> as FromParallelIterator<T>>::from_par_iter(par_iter))
}
}
#[cfg(feature = "rayon")]
impl<K, V, S> IntoParallelIterator for HashMap<K, V, S>
where
hb::HashMap<K, V, S>: IntoParallelIterator,
{
type Item = <hb::HashMap<K, V, S> as IntoParallelIterator>::Item;
type Iter = <hb::HashMap<K, V, S> as IntoParallelIterator>::Iter;
fn into_par_iter(self) -> Self::Iter {
self.0.into_par_iter()
}
}
#[cfg(feature = "rayon")]
impl<'a, K: Sync, V: Sync, S> IntoParallelIterator for &'a HashMap<K, V, S>
where
&'a hb::HashMap<K, V, S>: IntoParallelIterator,
{
type Item = <&'a hb::HashMap<K, V, S> as IntoParallelIterator>::Item;
type Iter = <&'a hb::HashMap<K, V, S> as IntoParallelIterator>::Iter;
fn into_par_iter(self) -> Self::Iter {
(&self.0).into_par_iter()
}
}
#[cfg(feature = "rayon")]
impl<'a, K: Sync, V: Sync, S> IntoParallelIterator for &'a mut HashMap<K, V, S>
where
&'a mut hb::HashMap<K, V, S>: IntoParallelIterator,
{
type Item = <&'a mut hb::HashMap<K, V, S> as IntoParallelIterator>::Item;
type Iter = <&'a mut hb::HashMap<K, V, S> as IntoParallelIterator>::Iter;
fn into_par_iter(self) -> Self::Iter {
(&mut self.0).into_par_iter()
}
}
#[cfg(feature = "rayon")]
impl<K, V, S, T> ParallelExtend<T> for HashMap<K, V, S>
where
hb::HashMap<K, V, S>: ParallelExtend<T>,
T: Send,
{
fn par_extend<I>(&mut self, par_iter: I)
where
I: IntoParallelIterator<Item = T>,
{
<hb::HashMap<K, V, S> as ParallelExtend<T>>::par_extend(&mut self.0, par_iter);
}
}
impl<K, V> HashMap<K, V, FixedHasher> {
#[inline]
pub const fn new() -> Self {
Self::with_hasher(FixedHasher)
}
#[inline]
pub fn with_capacity(capacity: usize) -> Self {
Self::with_capacity_and_hasher(capacity, FixedHasher)
}
}
impl<K, V, S> HashMap<K, V, S> {
#[inline]
pub const fn with_hasher(hash_builder: S) -> Self {
Self(hb::HashMap::with_hasher(hash_builder))
}
#[inline]
pub fn with_capacity_and_hasher(capacity: usize, hash_builder: S) -> Self {
Self(hb::HashMap::with_capacity_and_hasher(
capacity,
hash_builder,
))
}
#[inline]
pub fn hasher(&self) -> &S {
self.0.hasher()
}
#[inline]
pub fn capacity(&self) -> usize {
self.0.capacity()
}
#[inline]
pub fn keys(&self) -> Keys<'_, K, V> {
self.0.keys()
}
#[inline]
pub fn values(&self) -> Values<'_, K, V> {
self.0.values()
}
#[inline]
pub fn values_mut(&mut self) -> ValuesMut<'_, K, V> {
self.0.values_mut()
}
#[inline]
pub fn iter(&self) -> Iter<'_, K, V> {
self.0.iter()
}
#[inline]
pub fn iter_mut(&mut self) -> IterMut<'_, K, V> {
self.0.iter_mut()
}
#[inline]
pub fn len(&self) -> usize {
self.0.len()
}
#[inline]
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
#[inline]
pub fn drain(&mut self) -> Drain<'_, K, V> {
self.0.drain()
}
#[inline]
pub fn retain<F>(&mut self, f: F)
where
F: FnMut(&K, &mut V) -> bool,
{
self.0.retain(f);
}
#[inline]
pub fn extract_if<F>(&mut self, f: F) -> ExtractIf<'_, K, V, F>
where
F: FnMut(&K, &mut V) -> bool,
{
self.0.extract_if(f)
}
#[inline]
pub fn clear(&mut self) {
self.0.clear();
}
#[inline]
pub fn into_keys(self) -> IntoKeys<K, V> {
self.0.into_keys()
}
#[inline]
pub fn into_values(self) -> IntoValues<K, V> {
self.0.into_values()
}
#[inline]
pub fn into_inner(self) -> hb::HashMap<K, V, S> {
self.0
}
}
impl<K, V, S> HashMap<K, V, S>
where
K: Eq + Hash,
S: BuildHasher,
{
#[inline]
pub fn reserve(&mut self, additional: usize) {
self.0.reserve(additional);
}
#[inline]
pub fn try_reserve(&mut self, additional: usize) -> Result<(), hashbrown::TryReserveError> {
self.0.try_reserve(additional)
}
#[inline]
pub fn shrink_to_fit(&mut self) {
self.0.shrink_to_fit();
}
#[inline]
pub fn shrink_to(&mut self, min_capacity: usize) {
self.0.shrink_to(min_capacity);
}
#[inline]
pub fn entry(&mut self, key: K) -> Entry<'_, K, V, S> {
self.0.entry(key)
}
#[inline]
pub fn entry_ref<'a, 'b, Q>(&'a mut self, key: &'b Q) -> EntryRef<'a, 'b, K, Q, V, S>
where
Q: Hash + Equivalent<K> + ?Sized,
{
self.0.entry_ref(key)
}
#[inline]
pub fn get<Q>(&self, k: &Q) -> Option<&V>
where
Q: Hash + Equivalent<K> + ?Sized,
{
self.0.get(k)
}
#[inline]
pub fn get_key_value<Q>(&self, k: &Q) -> Option<(&K, &V)>
where
Q: Hash + Equivalent<K> + ?Sized,
{
self.0.get_key_value(k)
}
#[inline]
pub fn get_key_value_mut<Q>(&mut self, k: &Q) -> Option<(&K, &mut V)>
where
Q: Hash + Equivalent<K> + ?Sized,
{
self.0.get_key_value_mut(k)
}
#[inline]
pub fn contains_key<Q>(&self, k: &Q) -> bool
where
Q: Hash + Equivalent<K> + ?Sized,
{
self.0.contains_key(k)
}
#[inline]
pub fn get_mut<Q>(&mut self, k: &Q) -> Option<&mut V>
where
Q: Hash + Equivalent<K> + ?Sized,
{
self.0.get_mut(k)
}
#[inline]
pub fn get_disjoint_mut<Q, const N: usize>(&mut self, ks: [&Q; N]) -> [Option<&'_ mut V>; N]
where
Q: Hash + Equivalent<K> + ?Sized,
{
self.0.get_disjoint_mut(ks)
}
#[inline]
pub fn get_disjoint_key_value_mut<Q, const N: usize>(
&mut self,
ks: [&Q; N],
) -> [Option<(&'_ K, &'_ mut V)>; N]
where
Q: Hash + Equivalent<K> + ?Sized,
{
self.0.get_disjoint_key_value_mut(ks)
}
#[inline]
pub fn insert(&mut self, k: K, v: V) -> Option<V> {
self.0.insert(k, v)
}
#[inline]
pub fn try_insert(&mut self, key: K, value: V) -> Result<&mut V, OccupiedError<'_, K, V, S>> {
self.0.try_insert(key, value)
}
#[inline]
pub fn remove<Q>(&mut self, k: &Q) -> Option<V>
where
Q: Hash + Equivalent<K> + ?Sized,
{
self.0.remove(k)
}
#[inline]
pub fn remove_entry<Q>(&mut self, k: &Q) -> Option<(K, V)>
where
Q: Hash + Equivalent<K> + ?Sized,
{
self.0.remove_entry(k)
}
#[inline]
pub fn allocation_size(&self) -> usize {
self.0.allocation_size()
}
#[expect(
unsafe_code,
reason = "re-exporting unsafe method from Hashbrown requires unsafe code"
)]
#[inline]
pub unsafe fn insert_unique_unchecked(&mut self, key: K, value: V) -> (&K, &mut V) {
unsafe { self.0.insert_unique_unchecked(key, value) }
}
#[expect(
unsafe_code,
reason = "re-exporting unsafe method from Hashbrown requires unsafe code"
)]
#[inline]
pub unsafe fn get_disjoint_unchecked_mut<Q, const N: usize>(
&mut self,
keys: [&Q; N],
) -> [Option<&'_ mut V>; N]
where
Q: Hash + Equivalent<K> + ?Sized,
{
unsafe { self.0.get_disjoint_unchecked_mut(keys) }
}
#[expect(
unsafe_code,
reason = "re-exporting unsafe method from Hashbrown requires unsafe code"
)]
#[inline]
pub unsafe fn get_disjoint_key_value_unchecked_mut<Q, const N: usize>(
&mut self,
keys: [&Q; N],
) -> [Option<(&'_ K, &'_ mut V)>; N]
where
Q: Hash + Equivalent<K> + ?Sized,
{
unsafe { self.0.get_disjoint_key_value_unchecked_mut(keys) }
}
}