use std::borrow::Borrow;
use std::cell::{Cell, UnsafeCell};
use std::collections::hash_map::RandomState;
use std::collections::BTreeMap;
use std::collections::HashMap;
use std::hash::{BuildHasher, Hash};
use std::iter::FromIterator;
use std::ops::Index;
use stable_deref_trait::StableDeref;
pub struct FrozenMap<K, V, S = RandomState> {
map: UnsafeCell<HashMap<K, V, S>>,
in_use: Cell<bool>,
}
impl<K: Eq + Hash, V> FrozenMap<K, V> {
pub fn new() -> Self {
Self {
map: UnsafeCell::new(Default::default()),
in_use: Cell::new(false),
}
}
pub fn len(&self) -> usize {
assert!(!self.in_use.get());
self.in_use.set(true);
let len = unsafe {
let map = self.map.get();
(*map).len()
};
self.in_use.set(false);
len
}
pub fn is_empty(&self) -> bool {
self.len() == 0
}
}
impl<K: Eq + Hash, V: StableDeref, S: BuildHasher> FrozenMap<K, V, S> {
pub fn insert(&self, k: K, v: V) -> &V::Target {
assert!(!self.in_use.get());
self.in_use.set(true);
let ret = unsafe {
let map = self.map.get();
&*(*map).entry(k).or_insert(v)
};
self.in_use.set(false);
ret
}
pub fn get<Q>(&self, k: &Q) -> Option<&V::Target>
where
K: Borrow<Q>,
Q: Hash + Eq + ?Sized,
{
assert!(!self.in_use.get());
self.in_use.set(true);
let ret = unsafe {
let map = self.map.get();
(*map).get(k).map(|x| &**x)
};
self.in_use.set(false);
ret
}
pub fn map_get<Q, T, F>(&self, k: &Q, f: F) -> Option<T>
where
K: Borrow<Q>,
Q: Hash + Eq + ?Sized,
F: FnOnce(&V) -> T,
{
assert!(!self.in_use.get());
self.in_use.set(true);
let ret = unsafe {
let map = self.map.get();
(*map).get(k).map(f)
};
self.in_use.set(false);
ret
}
}
impl<K, V, S> FrozenMap<K, V, S> {
pub fn into_tuple_vec(self) -> Vec<(K, V)> {
self.map.into_inner().into_iter().collect::<Vec<_>>()
}
pub fn into_map(self) -> HashMap<K, V, S> {
self.map.into_inner()
}
}
impl<K: Eq + Hash + StableDeref, V: StableDeref, S: BuildHasher> FrozenMap<K, V, S> {
pub fn get_key_value<Q>(&self, k: &Q) -> Option<(&K::Target, &V::Target)>
where
K: Borrow<Q>,
Q: Hash + Eq + ?Sized,
{
assert!(!self.in_use.get());
self.in_use.set(true);
let ret = unsafe {
let map = self.map.get();
(*map).get_key_value(k).map(|(k, v)| (&**k, &**v))
};
self.in_use.set(false);
ret
}
}
impl<K, V, S> std::convert::AsMut<HashMap<K, V, S>> for FrozenMap<K, V, S> {
fn as_mut(&mut self) -> &mut HashMap<K, V, S> {
unsafe { &mut *self.map.get() }
}
}
impl<K, V, S> From<HashMap<K, V, S>> for FrozenMap<K, V, S> {
fn from(map: HashMap<K, V, S>) -> Self {
Self {
map: UnsafeCell::new(map),
in_use: Cell::new(false),
}
}
}
impl<Q: ?Sized, K, V, S> Index<&Q> for FrozenMap<K, V, S>
where
Q: Eq + Hash,
K: Eq + Hash + Borrow<Q>,
V: StableDeref,
S: BuildHasher,
{
type Output = V::Target;
fn index(&self, idx: &Q) -> &V::Target {
self.get(idx)
.expect("attempted to index FrozenMap with unknown key")
}
}
impl<K: Eq + Hash, V, S: BuildHasher + Default> FromIterator<(K, V)> for FrozenMap<K, V, S> {
fn from_iter<T>(iter: T) -> Self
where
T: IntoIterator<Item = (K, V)>,
{
let map: HashMap<_, _, _> = iter.into_iter().collect();
map.into()
}
}
impl<K: Eq + Hash, V, S: Default> Default for FrozenMap<K, V, S> {
fn default() -> Self {
Self {
map: UnsafeCell::new(Default::default()),
in_use: Cell::new(false),
}
}
}
impl<K: Clone, V: Clone, S: Clone> Clone for FrozenMap<K, V, S> {
fn clone(&self) -> Self {
assert!(!self.in_use.get());
self.in_use.set(true);
let self_clone = Self {
map: unsafe { self.map.get().as_ref().unwrap() }.clone().into(),
in_use: Cell::from(false),
};
self.in_use.set(false);
self_clone
}
}
impl<K: Eq + Hash, V: PartialEq + StableDeref> PartialEq for FrozenMap<K, V> {
fn eq(&self, other: &Self) -> bool {
assert!(!self.in_use.get());
assert!(!other.in_use.get());
self.in_use.set(true);
other.in_use.set(true);
let ret = unsafe { self.map.get().as_ref() == other.map.get().as_ref() };
self.in_use.set(false);
other.in_use.set(false);
ret
}
}
pub struct FrozenBTreeMap<K, V> {
map: UnsafeCell<BTreeMap<K, V>>,
in_use: Cell<bool>,
}
impl<K: Clone + Ord, V: StableDeref> FrozenBTreeMap<K, V> {
pub const fn new() -> Self {
Self {
map: UnsafeCell::new(BTreeMap::new()),
in_use: Cell::new(false),
}
}
pub fn len(&self) -> usize {
assert!(!self.in_use.get());
self.in_use.set(true);
let len = unsafe {
let map = self.map.get();
(*map).len()
};
self.in_use.set(false);
len
}
pub fn is_empty(&self) -> bool {
self.len() == 0
}
}
impl<K: Clone + Ord, V: StableDeref> FrozenBTreeMap<K, V> {
pub fn insert(&self, k: K, v: V) -> &V::Target {
assert!(!self.in_use.get());
self.in_use.set(true);
let ret = unsafe {
let map = self.map.get();
&*(*map).entry(k).or_insert(v)
};
self.in_use.set(false);
ret
}
pub fn get<Q>(&self, k: &Q) -> Option<&V::Target>
where
K: Borrow<Q>,
Q: Ord + ?Sized,
{
assert!(!self.in_use.get());
self.in_use.set(true);
let ret = unsafe {
let map = self.map.get();
(*map).get(k).map(|x| &**x)
};
self.in_use.set(false);
ret
}
pub fn map_get<Q, T, F>(&self, k: &Q, f: F) -> Option<T>
where
K: Borrow<Q>,
Q: Ord + ?Sized,
F: FnOnce(&V) -> T,
{
assert!(!self.in_use.get());
self.in_use.set(true);
let ret = unsafe {
let map = self.map.get();
(*map).get(k).map(f)
};
self.in_use.set(false);
ret
}
}
impl<K, V> FrozenBTreeMap<K, V> {
pub fn into_tuple_vec(self) -> Vec<(K, V)> {
self.map.into_inner().into_iter().collect::<Vec<_>>()
}
pub fn into_map(self) -> BTreeMap<K, V> {
self.map.into_inner()
}
}
impl<K, V> std::convert::AsMut<BTreeMap<K, V>> for FrozenBTreeMap<K, V> {
fn as_mut(&mut self) -> &mut BTreeMap<K, V> {
unsafe { &mut *self.map.get() }
}
}
impl<K: Clone + Ord, V: StableDeref> From<BTreeMap<K, V>> for FrozenBTreeMap<K, V> {
fn from(map: BTreeMap<K, V>) -> Self {
Self {
map: UnsafeCell::new(map),
in_use: Cell::new(false),
}
}
}
impl<Q: ?Sized, K, V> Index<&Q> for FrozenBTreeMap<K, V>
where
Q: Ord,
K: Clone + Ord + Borrow<Q>,
V: StableDeref,
{
type Output = V::Target;
fn index(&self, idx: &Q) -> &V::Target {
self.get(idx)
.expect("attempted to index FrozenBTreeMap with unknown key")
}
}
impl<K: Clone + Ord, V: StableDeref> FromIterator<(K, V)> for FrozenBTreeMap<K, V> {
fn from_iter<T>(iter: T) -> Self
where
T: IntoIterator<Item = (K, V)>,
{
let map: BTreeMap<_, _> = iter.into_iter().collect();
map.into()
}
}
impl<K: Clone + Ord, V: StableDeref> Default for FrozenBTreeMap<K, V> {
fn default() -> Self {
Self {
map: UnsafeCell::new(Default::default()),
in_use: Cell::new(false),
}
}
}
impl<K: Clone, V: Clone> Clone for FrozenBTreeMap<K, V> {
fn clone(&self) -> Self {
assert!(!self.in_use.get());
self.in_use.set(true);
let self_clone = Self {
map: unsafe { self.map.get().as_ref().unwrap() }.clone().into(),
in_use: Cell::from(false),
};
self.in_use.set(false);
self_clone
}
}
impl<K: Eq + Hash, V: PartialEq + StableDeref> PartialEq for FrozenBTreeMap<K, V> {
fn eq(&self, other: &Self) -> bool {
assert!(!self.in_use.get());
assert!(!other.in_use.get());
self.in_use.set(true);
other.in_use.set(true);
let ret = unsafe { self.map.get().as_ref() == other.map.get().as_ref() };
self.in_use.set(false);
other.in_use.set(false);
ret
}
}