use std::{marker, mem, ops};
use crate::depot::{
self,
queue::{
links,
round::{self, Lanes, phase},
},
};
#[derive(Clone, Copy)]
pub struct Lane<O> {
pub(in crate::depot::queue::round) owner: O,
pub(in crate::depot::queue::round) index: links::Index,
pub(super) item: marker::PhantomData<fn(O) -> O>,
}
impl<T, const G: usize, const N: usize, O: ops::Deref<Target = round::Lanes<T, G, N>>> Lane<O> {
pub fn try_new(owner: O, index: usize) -> Result<Self, round::Bounds> {
let capacity = owner.block.tail().len();
if index >= capacity {
return Err(round::Bounds::Lane { index, capacity });
}
Ok(Self {
owner,
index: unsafe { links::Index::new_usize(index) },
item: marker::PhantomData,
})
}
}
impl<T, const G: usize, const N: usize, O: ops::Deref<Target = round::Lanes<T, G, N>>>
depot::raw::Admit for depot::raw::Proof<Lane<O>, phase::Ready>
{
type Output = Option<round::Location<O, phase::Head>>;
fn admit(self) -> Self::Output {
let Lane {
owner, index: lane, ..
} = self.into_inner();
let track = unsafe { owner.block.tail().get_unchecked(lane.get()) };
let index = track.first()?;
Some(round::Location::new(owner, round::Position { lane, index }))
}
}
impl<T, const G: usize, const N: usize> Lane<&mut round::Lanes<T, G, N>> {
pub fn dequeue(&mut self) -> Option<round::Location<&mut round::Lanes<T, G, N>, round::Idle>> {
let lane = Lane {
owner: &mut *self.owner,
index: self.index,
item: marker::PhantomData,
};
Some(
depot::raw::Admit::admit(unsafe { depot::raw::Proof::<_, phase::Ready>::new(lane) })?
.remove::<true>(),
)
}
}
impl<'a, T, const G: usize, const N: usize> Lane<&'a round::Lanes<T, G, N>> {
pub fn front(&self) -> Option<round::Snapshot<&'a round::Lanes<T, G, N>, round::Front>> {
let head =
depot::raw::Admit::admit(unsafe { depot::raw::Proof::<_, phase::Ready>::new(*self) })?;
Some(round::Snapshot::new(head.owner, head.position))
}
pub fn pop_front(&self) -> Option<&'a T> {
Some(
depot::raw::Admit::admit(unsafe { depot::raw::Proof::<_, phase::Ready>::new(*self) })?
.pop(),
)
}
pub fn rotate(&self) -> Option<round::Snapshot<&'a round::Lanes<T, G, N>, round::Front>> {
let head =
depot::raw::Admit::admit(unsafe { depot::raw::Proof::<_, phase::Ready>::new(*self) })?
.rotate();
Some(round::Snapshot::new(head.owner, head.position))
}
}
const _: () = {
let word = mem::size_of::<usize>();
assert!(mem::size_of::<Lane<&Lanes<(), 1>>>() == 2 * word);
assert!(mem::size_of::<Option<Lane<&Lanes<(), 1>>>>() == 2 * word);
assert!(mem::size_of::<Lane<&mut Lanes<(), 1>>>() == 2 * word);
assert!(mem::size_of::<Option<Lane<&mut Lanes<(), 1>>>>() == 2 * word);
};