use std::{cell::Cell, mem::MaybeUninit, ops::Range};
use crate::buffer::{Buffer, CellBuffer, Drain, Resize};
pub struct VecBuffer<T>(Box<[Cell<MaybeUninit<T>>]>);
impl<T> Default for VecBuffer<T> {
fn default() -> Self {
Self(Default::default())
}
}
unsafe impl<T> Buffer for VecBuffer<T> {
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> CellBuffer<T> for VecBuffer<T> {
unsafe fn insert(&self, index: usize, value: T) {
self.0[index].set(MaybeUninit::new(value));
}
}
impl<T> Resize for VecBuffer<T> {
fn resize(&mut self, capacity: usize) {
self.0 = (0..capacity)
.map(|_| Cell::new(MaybeUninit::uninit()))
.collect();
}
}
unsafe impl<T> Drain for VecBuffer<T> {
type Value = T;
#[inline]
unsafe fn remove(&mut self, index: usize) -> Self::Value {
unsafe { self.0[index].get_mut().assume_init_read() }
}
}