use std::mem;
use crate::{
depot::{arena::linked::slots, index::Initialized, queue::pool},
mem::{Lease, lease},
};
pub struct Front<'a, T, S, const TRACK: bool = true> {
lane: pool::Lane<'a, T, S, TRACK>,
index: slots::Index,
}
impl<'a, T, S, const TRACK: bool> Front<'a, T, S, TRACK> {
pub fn from_source(
source: crate::depot::raw::Proof<
(pool::Lane<'a, T, S, TRACK>, slots::Index),
Initialized<pool::Head>,
>,
) -> Self {
let (lane, index) = source.into_inner();
Self { lane, index }
}
pub fn into_parts(self) -> (pool::Lane<'a, T, S, TRACK>, slots::Index) {
(self.lane, self.index)
}
pub(in crate::depot::queue::pool::lane) const fn new(
lane: pool::Lane<'a, T, S, TRACK>,
index: slots::Index,
) -> Self {
Self { lane, index }
}
pub fn get_mut(&mut self) -> &mut T {
self.parts_mut().0
}
pub fn parts_mut(&mut self) -> (&mut T, &mut S) {
let value = unsafe { &mut *self.lane.store.value_ptr(self.index) };
(value, &mut self.lane.slot.state)
}
pub fn take(self) -> (T, pool::Lane<'a, T, S, TRACK>) {
let value = unsafe {
self.lane
.slot
.queue
.pop::<_, TRACK>(self.lane.store, self.index)
};
(value, self.lane)
}
pub fn pop(self) -> T {
self.take().0
}
}
impl<'a, T, S> Front<'a, T, S> {
pub fn remove_with<R>(
mut self,
remove: impl for<'b> FnOnce(Lease<slots::Vacant<T, slots::Bound<'b, T>>, lease::Open>) -> R,
) -> (pool::Lane<'a, T, S>, R) {
let result = remove(Front::new(self.lane.borrow_mut(), self.index).remove());
(self.lane, result)
}
pub fn remove(self) -> Lease<slots::Vacant<T, slots::Bound<'a, T>>, lease::Open> {
let lane = self.lane;
let (value, claim) = unsafe { lane.slot.queue.take(lane.store, self.index) };
Lease::open(unsafe { claim.bind(&mut lane.slot.queue) }, value)
}
}
const _: () = {
assert!(mem::size_of::<Front<'static, u64, ()>>() == 3 * mem::size_of::<usize>());
assert!(
mem::size_of::<Option<Front<'static, u64, ()>>>()
== mem::size_of::<Front<'static, u64, ()>>()
);
assert!(
mem::size_of::<(u64, pool::Lane<'static, u64>)>()
== mem::size_of::<Front<'static, u64, ()>>()
);
};