use std::{cell::Cell, mem::MaybeUninit, ops::Range};
use crate::{
buffer::{Buffer, CellBuffer, Drain},
utils::init_array,
};
pub struct ArrayBuffer<T, const N: usize>([Cell<MaybeUninit<T>>; N]);
impl<T, const N: usize> Default for ArrayBuffer<T, N> {
fn default() -> Self {
Self(init_array(|| Cell::new(MaybeUninit::uninit())))
}
}
unsafe impl<T, const N: usize> Buffer for ArrayBuffer<T, N> {
type Slice<'a> = &'a mut [T]
where
T: 'a;
#[inline]
fn capacity(&self) -> usize {
self.0.len()
}
#[inline]
unsafe fn slice(&mut self, range: Range<usize>) -> Self::Slice<'_> {
unsafe { &mut *(&mut self.0[range] as *mut _ as *mut [T]) }
}
#[inline]
unsafe fn clear(&mut self, range: Range<usize>) {
for index in range {
unsafe { self.remove(index) };
}
}
}
unsafe impl<T, const N: usize> CellBuffer<T> for ArrayBuffer<T, N> {
unsafe fn insert(&self, index: usize, value: T) {
self.0[index].set(MaybeUninit::new(value));
}
}
unsafe impl<T, const N: usize> Drain for ArrayBuffer<T, N> {
type Value = T;
#[inline]
unsafe fn remove(&mut self, index: usize) -> Self::Value {
unsafe { self.0[index].replace(MaybeUninit::uninit()).assume_init() }
}
}