use core::alloc::Layout;
use core::fmt::Debug;
use core::mem::MaybeUninit;
use core::ptr::NonNull;
use core::slice;
use crate::alloc::Allocator;
use crate::capacity::Index;
use crate::error::StorageError;
use crate::storage::{BufferHeader, FatBuffer, InlineBuffer, RawBuffer, ThinBuffer};
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub struct VecHeader<I: Index = usize> {
pub capacity: I,
pub length: I,
}
impl<T, I: Index> BufferHeader<T> for VecHeader<I> {
const EMPTY: Self = VecHeader {
capacity: I::ZERO,
length: I::ZERO,
};
#[inline]
fn is_empty(&self) -> bool {
self.capacity == I::ZERO
}
#[inline]
fn layout(&self) -> Result<Layout, core::alloc::LayoutError> {
Layout::array::<T>(self.capacity.to_usize())
}
#[inline]
fn update_for_alloc(&mut self, ptr: NonNull<[u8]>, exact: bool) -> NonNull<T> {
if !exact {
let t_size = size_of::<T>();
self.capacity = if t_size > 0 {
I::from_usize((ptr.len() / t_size).min(I::MAX_USIZE))
} else {
I::from_usize(I::MAX_USIZE)
};
}
ptr.cast()
}
}
#[derive(Debug)]
pub struct VecData<T, I: Index = usize>(T, I);
pub trait VecBuffer: RawBuffer<RawData = Self::Item> {
type Item;
type Index: Index;
fn capacity(&self) -> Self::Index;
fn length(&self) -> Self::Index;
unsafe fn set_length(&mut self, len: Self::Index);
#[inline]
fn as_uninit_slice(&mut self) -> &mut [MaybeUninit<Self::Item>] {
unsafe { slice::from_raw_parts_mut(self.data_ptr_mut().cast(), self.capacity().to_usize()) }
}
#[inline]
fn as_slice(&self) -> &[Self::Item] {
unsafe { slice::from_raw_parts(self.data_ptr(), self.length().to_usize()) }
}
#[inline]
fn as_mut_slice(&mut self) -> &mut [Self::Item] {
unsafe { slice::from_raw_parts_mut(self.data_ptr_mut(), self.length().to_usize()) }
}
#[inline]
unsafe fn uninit_index(&mut self, index: usize) -> &mut MaybeUninit<Self::Item> {
&mut *self.data_ptr_mut().add(index).cast()
}
fn grow_buffer(&mut self, capacity: Self::Index, exact: bool) -> Result<(), StorageError>;
fn shrink_buffer(&mut self, capacity: Self::Index) -> Result<(), StorageError>;
}
impl<T, I: Index, A: Allocator> VecBuffer for FatBuffer<T, VecHeader<I>, A> {
type Item = T;
type Index = I;
#[inline]
fn capacity(&self) -> I {
self.header.capacity
}
#[inline]
fn length(&self) -> I {
self.header.length
}
#[inline]
unsafe fn set_length(&mut self, len: I) {
self.header.length = len;
}
#[inline]
fn grow_buffer(&mut self, capacity: Self::Index, exact: bool) -> Result<(), StorageError> {
let length = self.length();
self.grow(VecHeader { capacity, length }, exact)?;
Ok(())
}
#[inline]
fn shrink_buffer(&mut self, capacity: Self::Index) -> Result<(), StorageError> {
let length = self.length();
self.shrink(VecHeader { capacity, length })?;
Ok(())
}
}
impl<T, I: Index, A: Allocator> VecBuffer for ThinBuffer<T, VecHeader<I>, A> {
type Item = T;
type Index = I;
#[inline]
fn capacity(&self) -> I {
self.header().capacity
}
#[inline]
fn length(&self) -> I {
self.header().length
}
#[inline]
unsafe fn set_length(&mut self, len: I) {
self.set_header(VecHeader {
capacity: self.capacity(),
length: len,
});
}
#[inline]
fn grow_buffer(&mut self, capacity: Self::Index, exact: bool) -> Result<(), StorageError> {
let length = self.length();
self.grow(VecHeader { capacity, length }, exact)?;
Ok(())
}
#[inline]
fn shrink_buffer(&mut self, capacity: Self::Index) -> Result<(), StorageError> {
let length = self.length();
self.shrink(VecHeader { capacity, length })?;
Ok(())
}
}
impl<'a, T: 'a, const N: usize> VecBuffer for InlineBuffer<T, N> {
type Item = T;
type Index = usize;
#[inline]
fn capacity(&self) -> usize {
N
}
#[inline]
fn length(&self) -> usize {
self.length
}
#[inline]
unsafe fn set_length(&mut self, len: usize) {
self.length = len;
}
#[inline]
fn grow_buffer(&mut self, capacity: Self::Index, exact: bool) -> Result<(), StorageError> {
if (!exact && capacity.to_usize() < N) || capacity.to_usize() == N {
Ok(())
} else {
Err(StorageError::CapacityLimit)
}
}
#[inline]
fn shrink_buffer(&mut self, _capacity: Self::Index) -> Result<(), StorageError> {
Ok(())
}
}