use std::{marker, mem};
use crate::{
alloc,
depot::{
arena::{
linked,
linked::{fifo, head, slots},
},
capacity,
queue::pool::fifo::Fifo,
},
};
pub struct Arena<T, Tag = (), const TRACK: bool = true> {
pub(in crate::depot) inner: slots::Store<T>,
domain: marker::PhantomData<fn(Tag) -> Tag>,
}
impl<T, Tag, const TRACK: bool> Arena<T, Tag, TRACK> {
pub fn try_new<N: capacity::Extent>(capacity: N) -> Result<Self, alloc::Error> {
let capacity = slots::Capacity::new(capacity)?;
let bundle = capacity.bundle();
let nodes = bundle.try_allocate()?.root();
Ok(Self {
inner: unsafe { slots::Store::new(nodes, capacity) },
domain: marker::PhantomData,
})
}
}
impl<T, const TRACK: bool> Arena<T, (), TRACK> {
pub const fn fifo(&self) -> Fifo<'_, T, TRACK> {
Fifo::new(self)
}
}
impl<T, Tag> Arena<T, Tag> {
pub fn available(&self) -> usize {
self.inner.available()
}
pub fn vacant(&self) -> Option<slots::Vacant<T, &'_ slots::Store<T>, Tag>> {
self.inner.vacant()
}
pub fn permit(&mut self) -> Option<slots::Permit<'_, T, Tag>> {
self.inner.permit()
}
pub unsafe fn back_mut(&mut self, back: fifo::Back<Tag>) -> &mut T {
unsafe { self.inner.back_mut(back) }
}
pub unsafe fn iter<'a>(&'a self, state: &'a head::List<Tag>) -> linked::Iter<'a, T, Tag> {
unsafe { state.iter(&self.inner) }
}
pub unsafe fn cursor<'a>(
&'a self,
state: &'a mut head::List<Tag>,
) -> slots::Cursor<'a, T, Tag> {
unsafe { state.cursor(&self.inner) }
}
pub unsafe fn front_entry<'a, 'b>(
&'a self,
state: &'b mut head::List<Tag>,
) -> Option<slots::Entry<'a, 'b, T, Tag>> {
unsafe { state.front_entry(&self.inner) }
}
pub unsafe fn pop_front(&self, state: &mut head::List<Tag>) -> Option<T> {
Some(unsafe { state.front_entry(&self.inner) }?.pop())
}
pub unsafe fn queue<'a>(&'a self, state: &'a mut fifo::Fifo<Tag>) -> slots::Bound<'a, T, Tag> {
unsafe { state.queue(&self.inner) }
}
}
impl<T, Tag, const TRACK: bool> Drop for Arena<T, Tag, TRACK> {
fn drop(&mut self) {
unsafe { self.inner.drop_values() };
let bundle = self.inner.region.capacity().bundle();
unsafe { bundle.deallocate(self.inner.region.pointer()) };
}
}
const _: () = assert!(mem::size_of::<Arena<u64>>() == 3 * mem::size_of::<usize>());
mod pool;
pub(in crate::depot) use pool::{PoolMutable, PoolOwner, PoolPolicy, PoolSharing};
mod queues;
pub(in crate::depot) use queues::{QueueBlock, QueueSlot};
mod slabs;
pub(in crate::depot) use slabs::{SlabCapacity, SlabLinks, SlabSlot};
mod indexed;
pub(in crate::depot) use indexed::{IndexedBlock, IndexedHook, IndexedMeta, IndexedState};
mod staged;
pub(in crate::depot) use staged::{Retired, StagedMove, StagedNode, StagedPhase, StagedState};
mod owners;
pub(crate) use owners::SlotOwner;
mod ends;
pub(crate) use ends::EndsPop;