use std::{mem, ptr, slice};
use crate::depot::{self, queue::ring};
pub(crate) unsafe trait RingRead: depot::raw::RingStore {
fn front(&self) -> Option<&Self::Item> {
if self.state().is_empty() {
return None;
}
Some(unsafe { &*self.entries().add(self.state().head()).cast::<Self::Item>() })
}
fn get(&self, index: usize) -> Option<&Self::Item> {
if index >= self.state().len() {
return None;
}
let position = unsafe { self.state().position(self.capacity(), index) };
Some(unsafe { &*self.entries().add(position).cast::<Self::Item>() })
}
fn as_slices(&self) -> (&[Self::Item], &[Self::Item]) {
let state = self.state();
let (start, [front, back]) = state.prefix(self.capacity(), state.len());
let entries = self.entries().cast::<Self::Item>();
unsafe {
(
slice::from_raw_parts(entries.add(start), front),
slice::from_raw_parts(entries, back),
)
}
}
}
pub(crate) unsafe trait RingDestroy: depot::raw::RingCell {
fn clear(&self) {
loop {
let mut state = self.state();
if state.is_empty() {
return;
}
let index = unsafe { state.pop_front(self.capacity()) };
unsafe { self.publish(state) };
unsafe {
self.entries()
.cast_mut()
.add(index)
.cast::<Self::Item>()
.drop_in_place()
};
}
}
}
pub(crate) unsafe fn drop_ring<S: depot::raw::RingEdit + ?Sized>(source: &mut S) {
if mem::needs_drop::<S::Item>() {
let (front, back) = unsafe { depot::raw::RingEdit::slices_mut(source) };
unsafe {
ptr::drop_in_place(front);
ptr::drop_in_place(back);
}
}
}
unsafe impl<T> crate::depot::raw::RingEdit for ring::Fifo<T> {
unsafe fn parts_mut(&mut self) -> (&mut ring::State<u32>, &mut [mem::MaybeUninit<T>]) {
(&mut self.state, &mut self.block)
}
}
unsafe impl<T> crate::depot::raw::RingCell for ring::Cell<T> {
unsafe fn publish(&self, state: ring::State<u32>) {
self.state.set(state);
}
}
unsafe impl<T> crate::depot::raw::RingEdit for ring::Cell<T> {
unsafe fn parts_mut(&mut self) -> (&mut ring::State<u32>, &mut [mem::MaybeUninit<T>]) {
(self.state.get_mut(), &mut self.block)
}
}
unsafe impl<T> crate::depot::raw::RingEdit for ring::Pool<T> {
unsafe fn parts_mut(&mut self) -> (&mut ring::State<u32>, &mut [mem::MaybeUninit<T>]) {
(self.state.get_mut(), &mut self.block)
}
}
unsafe impl<T> crate::depot::raw::RingCell for ring::Pool<T> {
unsafe fn publish(&self, state: ring::State<u32>) {
self.state.set(state);
}
}
unsafe impl<T> crate::depot::raw::RingStore for ring::Fifo<T> {
type Item = T;
type Word = u32;
fn state(&self) -> ring::State<u32> {
self.state
}
fn capacity(&self) -> usize {
self.capacity()
}
fn entries(&self) -> *const mem::MaybeUninit<T> {
self.block.as_ptr()
}
}
unsafe impl<T> crate::depot::raw::RingRead for ring::Fifo<T> {}
unsafe impl<T> crate::depot::raw::RingStore for ring::Cell<T> {
type Item = T;
type Word = u32;
fn state(&self) -> ring::State<u32> {
self.state.get()
}
fn capacity(&self) -> usize {
self.capacity()
}
fn entries(&self) -> *const mem::MaybeUninit<T> {
self.block.as_ptr()
}
}
unsafe impl<T> crate::depot::raw::RingDestroy for ring::Cell<T> {}
unsafe impl<T> crate::depot::raw::RingStore for ring::Pool<T> {
type Item = T;
type Word = u32;
fn state(&self) -> ring::State<u32> {
self.state.get()
}
fn capacity(&self) -> usize {
self.capacity()
}
fn entries(&self) -> *const mem::MaybeUninit<T> {
self.block.as_ptr()
}
}