use std::{mem::MaybeUninit, slice};
use crate::{buffer, depot::arena::linked::slots};
pub(in crate::buffer) unsafe trait Prefix {
fn prefix(&self) -> (*mut MaybeUninit<u8>, u32);
fn as_slice(&self) -> &[u8] {
let (pointer, len) = self.prefix();
unsafe { buffer::raw::range(pointer.cast(), 0, len as usize) }
}
}
pub(in crate::buffer) unsafe trait Exclusive: Prefix {
fn as_mut_ptr(&mut self) -> *mut MaybeUninit<u8>;
fn len_mut(&mut self) -> &mut u32;
fn capacity(&self) -> u32;
fn as_mut_slice(&mut self) -> &mut [u8] {
let pointer = self.as_mut_ptr();
let len = self.len_mut();
unsafe { buffer::raw::range_mut(pointer.cast(), 0, *len as usize) }
}
fn spare_parts(&mut self) -> (&mut u32, &mut [MaybeUninit<u8>]) {
let capacity = self.capacity();
let pointer = self.as_mut_ptr();
let len = self.len_mut();
let used = *len as usize;
let spare =
unsafe { slice::from_raw_parts_mut(pointer.add(used), capacity as usize - used) };
(len, spare)
}
fn fill(&mut self, byte: u8) {
let capacity = self.capacity();
let pointer = self.as_mut_ptr();
let len = self.len_mut();
unsafe {
pointer
.add(*len as usize)
.cast::<u8>()
.write_bytes(byte, (capacity - *len) as usize);
}
*len = capacity;
}
}
pub(in crate::buffer) unsafe trait Indexed<'a>: Sized {
type Item: 'a;
fn parts(self) -> (&'a slots::Store<Self::Item>, slots::Index);
fn get(self) -> &'a Self::Item {
let (store, index) = self.parts();
unsafe { store.value(index) }
}
}
pub(in crate::buffer) unsafe trait IndexedMut<'a>: Indexed<'a> {
fn get_mut(self) -> &'a mut Self::Item {
let (store, index) = self.parts();
unsafe { &mut *store.value_ptr(index) }
}
}
pub(in crate::buffer) unsafe trait Linked<'a>: Sized {
type Item: 'a;
type Metadata: 'a;
fn parts(
self,
) -> (
&'a slots::Store<Self::Item>,
&'a slots::Store<Self::Metadata>,
slots::Index,
);
fn head(metadata: &Self::Metadata) -> slots::Index;
fn metadata(self) -> &'a Self::Metadata {
let (_, descs, index) = self.parts();
unsafe { descs.value(index) }
}
fn front(self) -> &'a Self::Item {
let (nodes, descs, index) = self.parts();
let desc = unsafe { descs.value(index) };
unsafe { nodes.value(Self::head(desc)) }
}
}
pub(in crate::buffer) unsafe trait LinkedMut<'a>: Linked<'a> {
fn front_mut(self) -> (&'a mut Self::Metadata, &'a mut Self::Item) {
let (nodes, descs, index) = self.parts();
unsafe {
let desc = &mut *descs.value_ptr(index);
let item = &mut *nodes.value_ptr(Self::head(desc));
(desc, item)
}
}
}