use { crate::{ clonecell::UnsafeCellCloneSafe, ptr_ext::{MutPtrExt, PtrExt}, }, ahash::AHashMap, std::{ borrow::Borrow, cell::UnsafeCell, fmt::{Debug, Formatter}, hash::Hash, mem, ops::{Deref, DerefMut}, }, }; pub struct CopyHashMap { map: UnsafeCell>, } impl Debug for CopyHashMap { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { self.map.fmt(f) } } impl Default for CopyHashMap { fn default() -> Self { Self { map: Default::default(), } } } impl CopyHashMap { pub fn new() -> Self { Self::default() } pub fn set(&self, k: K, v: V) -> Option { unsafe { self.map.get().deref_mut().insert(k, v) } } pub fn get(&self, k: &Q) -> Option where V: UnsafeCellCloneSafe, Q: Hash + Eq + ?Sized, K: Borrow, { unsafe { self.map.get().deref().get(k).cloned() } } pub fn remove(&self, k: &Q) -> Option where Q: Hash + Eq + ?Sized, K: Borrow, { unsafe { self.map.get().deref_mut().remove(k) } } pub fn contains(&self, k: &Q) -> bool where Q: Hash + Eq + ?Sized, K: Borrow, { unsafe { self.map.get().deref().contains_key(k) } } pub fn not_contains(&self, k: &Q) -> bool where Q: Hash + Eq + ?Sized, K: Borrow, { !self.contains(k) } pub fn lock(&self) -> Locked<'_, K, V> { Locked { source: self, map: self.clear(), } } pub fn clear(&self) -> AHashMap { unsafe { mem::take(self.map.get().deref_mut()) } } pub fn is_empty(&self) -> bool { unsafe { self.map.get().deref().is_empty() } } pub fn is_not_empty(&self) -> bool { !self.is_empty() } pub fn len(&self) -> usize { unsafe { self.map.get().deref().len() } } } pub struct Locked<'a, K, V> { source: &'a CopyHashMap, map: AHashMap, } impl<'a, K, V> Drop for Locked<'a, K, V> { fn drop(&mut self) { unsafe { mem::swap(&mut self.map, self.source.map.get().deref_mut()); } } } impl<'a, K, V> Deref for Locked<'a, K, V> { type Target = AHashMap; fn deref(&self) -> &Self::Target { &self.map } } impl<'a, K, V> DerefMut for Locked<'a, K, V> { fn deref_mut(&mut self) -> &mut Self::Target { &mut self.map } }