use std::ops;
use crate::depot::queue::links;
pub unsafe trait Hooks {
unsafe fn chain_push<C: crate::depot::raw::ChainCount>(
&self,
chain: &links::Chain<C>,
index: links::Index,
) {
unsafe { chain.link_back(self, index) };
}
unsafe fn chain_unlink<'a, C: crate::depot::raw::ChainCount>(
&'a self,
chain: &'a links::Chain<C>,
index: links::Index,
) -> links::Detached<'a> {
unsafe { chain.unlink(self, index) }
}
unsafe fn chain_pop<'a, C: crate::depot::raw::ChainCount>(
&'a self,
chain: &'a links::Chain<C>,
index: links::Index,
) -> links::Detached<'a> {
let change = unsafe { crate::depot::raw::Pop::at(chain, self, index) };
crate::depot::raw::Removal::commit(change)
}
unsafe fn cycle_step(&self, cycle: &links::Cycle, index: links::Index) -> links::Index {
unsafe { cycle.next_live(self, index) }
}
unsafe fn cycle_push(&self, cycle: &links::Cycle, index: links::Index) {
unsafe { cycle.push(self, index) };
}
unsafe fn cycle_unlink(&self, cycle: &links::Cycle, index: links::Index) {
unsafe { cycle.unlink_key(self, index) };
}
unsafe fn acquire(&self, free: &links::Free) -> Option<links::Index> {
unsafe { free.acquire_raw(self) }
}
unsafe fn recycle(&self, free: &links::Free, index: links::Index) {
unsafe { free.recycle_now(self, index) }
}
unsafe fn push(&self, detached: links::Detached<'_>, chain: &links::Chain) {
unsafe { detached.push(chain, self) }
}
unsafe fn hook_raw(&self, index: links::Index) -> &links::Hook;
unsafe fn link_raw(&mut self, list: &links::List, index: links::Index) {
let domain = &*self;
let hook = unsafe { domain.hook_raw(index) };
let adjacent = list.first().map(|next| {
(next, unsafe { domain.hook_raw(next) }.into())
});
unsafe {
EndpointHook::from(hook).push::<true, _>(list, index, links::Index::END, adjacent)
};
}
unsafe fn unlink_raw(&mut self, list: &links::List, index: links::Index) {
let domain = &*self;
let hook = unsafe { domain.hook_raw(index) };
let prev = hook.previous.get();
let next = hook.next.get();
let prior = match links::Index::decode(prev) {
Some(key) => Neighbor::node(prev, unsafe { domain.hook_raw(key) }.into()),
None => Neighbor::head(prev, list),
};
let after = match links::Index::decode(next) {
Some(key) => Neighbor::node(next, unsafe { domain.hook_raw(key) }.into()),
None => Neighbor::head(next, list),
};
unsafe { EndpointHook::from(hook).detach(index, prior, after) };
}
}
#[derive(Debug)]
#[repr(C)]
pub struct Node<T> {
value: T,
hook: links::Hook,
}
impl<T> Node<T> {
pub fn vacant(value: T, index: u32, next: u32) -> Self {
Self {
value,
hook: links::Hook::vacant(index, next),
}
}
pub const fn hook(&self) -> &links::Hook {
&self.hook
}
}
impl<T> ops::Deref for Node<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
&self.value
}
}
unsafe impl<T> Hooks for [Node<T>] {
unsafe fn hook_raw(&self, index: links::Index) -> &links::Hook {
unsafe { self.get_unchecked(index.get()) }.hook()
}
}
mod endpoint;
mod member;
mod mutation;
pub(in crate::depot) use endpoint::{EndpointHook, EndpointWord, Neighbor};
pub(in crate::depot) use member::Removal;
pub(in crate::depot) use mutation::{Detach, Insert, Pop, Splice};
mod lanes;
pub(in crate::depot) use lanes::{LaneInit, LaneStore, LaneUndo};