use std::marker;
use crate::depot::{map::direct, queue::links, raw::Live};
pub struct Occupied<'a, K: crate::depot::raw::Key, V, P = ()> {
pub(in crate::depot::map::direct) table: &'a mut direct::Table<K, V>,
pub(in crate::depot::map::direct) key: K,
pub(in crate::depot::map::direct) plane: marker::PhantomData<fn(P) -> P>,
}
impl<'a, K: crate::depot::raw::Key, V> Occupied<'a, K, V> {
pub fn from_live<C, P>(
live: Live<(&'a mut direct::Table<K, V>, C), links::Index, P>,
) -> (Occupied<'a, K, V, P>, C) {
let ((table, context), index) = live.into_inner();
let slot = unsafe { table.block.get_unchecked(index.get()) };
let key = K::from_live(unsafe { slot.key.live() });
(
Occupied {
table,
key,
plane: marker::PhantomData,
},
context,
)
}
}
impl<'a, K: crate::depot::raw::Key, V, P> Occupied<'a, K, V, P> {
pub fn key(&self) -> K {
self.key
}
pub(in crate::depot) fn index(&self) -> usize {
self.key.index()
}
pub(in crate::depot) fn table(&self) -> &direct::Table<K, V> {
self.table
}
fn slot(&self) -> &direct::raw::Entry<K, V> {
unsafe { self.table.block.get_unchecked(self.key.index()) }
}
fn slot_mut(&mut self) -> &mut direct::raw::Entry<K, V> {
unsafe { self.table.block.get_unchecked_mut(self.key.index()) }
}
fn into_slot(self) -> &'a mut direct::raw::Entry<K, V> {
unsafe { self.table.block.get_unchecked_mut(self.key.index()) }
}
pub fn get(&self) -> &V {
unsafe { self.slot().value.assume_init_ref() }
}
pub(in crate::depot) fn get_mut(&mut self) -> &mut V {
unsafe { self.slot_mut().value.assume_init_mut() }
}
pub fn into_mut(self) -> &'a mut V {
unsafe { self.into_slot().value.assume_init_mut() }
}
pub fn remove(self) -> V {
self.take().1
}
pub fn take(self) -> (direct::Vacant<'a, K, V, P>, V) {
let index = unsafe { links::Index::new_usize(self.index()) };
unsafe { self.take_at(index) }
}
pub(in crate::depot) unsafe fn take_at(
self,
index: links::Index,
) -> (direct::Vacant<'a, K, V, P>, V) {
let value = unsafe { self.table.vacate(index).assume_init_read() };
(
direct::Vacant {
table: self.table,
key: self.key,
plane: marker::PhantomData,
},
value,
)
}
pub fn discard(self) {
let index = unsafe { links::Index::new_usize(self.index()) };
unsafe { self.discard_at(index) };
}
pub(in crate::depot) unsafe fn discard_at(self, index: links::Index) {
unsafe { self.table.vacate(index).assume_init_drop() };
}
}