use std::{cell, mem};
use crate::depot::queue::links;
#[repr(transparent)]
pub struct Free(cell::Cell<Option<links::Index>>);
impl Free {
pub fn seeded(cap: usize) -> Self {
Self(cell::Cell::new(
(cap != 0).then_some(unsafe { links::Index::new_raw(0) }),
))
}
pub(in crate::depot) fn front(&self) -> Option<links::Index> {
self.0.get()
}
pub(in crate::depot) unsafe fn acquire_raw<H: crate::depot::raw::Hooks + ?Sized>(
&self,
hooks: &H,
) -> Option<links::Index> {
let index = self.front()?;
unsafe { self.acquire_at(hooks, index) };
Some(index)
}
pub(in crate::depot) unsafe fn acquire_at<H: crate::depot::raw::Hooks + ?Sized>(
&self,
hooks: &H,
index: links::Index,
) {
let hook = unsafe { hooks.hook_raw(index) };
let next = hook.next.replace(links::Index::END);
self.0.set(links::Index::decode(next));
}
pub fn recycle(&self, vacant: links::Detached<'_>) {
let (hook, index) = vacant.into_parts();
hook.previous.set(index.raw());
hook.next.set(links::Index::encode(self.0.get()));
self.0.set(Some(index));
}
pub(in crate::depot) unsafe fn recycle_now<H: crate::depot::raw::Hooks + ?Sized>(
&self,
hooks: &H,
index: links::Index,
) {
self.recycle(unsafe { links::Detached::new(hooks.hook_raw(index), index) });
}
}
const _: () = assert!(mem::size_of::<Free>() == mem::size_of::<u32>());