use std::marker::PhantomData;
#[derive(Debug)]
pub struct UnalignedSlice<'a, T> {
ptr: *const T,
len: usize,
_lifetime: PhantomData<&'a T>,
}
impl<'a, T> UnalignedSlice<'a, T> {
pub const unsafe fn new(ptr: *const T, len: usize) -> Self {
Self {
ptr,
len,
_lifetime: PhantomData,
}
}
pub const fn len(&self) -> usize {
self.len
}
pub const fn is_empty(&self) -> bool {
self.len() == 0
}
pub const fn as_ptr(&self) -> *const T {
self.ptr
}
}
impl<T> Clone for UnalignedSlice<'_, T> {
fn clone(&self) -> Self {
*self
}
}
impl<T> Copy for UnalignedSlice<'_, T> {}
impl<'a, T> From<&'a [T]> for UnalignedSlice<'a, T> {
fn from(slice: &'a [T]) -> Self {
unsafe { Self::new(slice.as_ptr(), slice.len()) }
}
}
impl<'a, T, const N: usize> From<&'a [T; N]> for UnalignedSlice<'a, T> {
fn from(slice: &'a [T; N]) -> Self {
unsafe { Self::new(slice.as_ptr(), N) }
}
}
pub trait AsUnaligned {
type Element;
fn as_unaligned(&self) -> UnalignedSlice<'_, Self::Element>;
}
impl<T> AsUnaligned for UnalignedSlice<'_, T> {
type Element = T;
fn as_unaligned(&self) -> UnalignedSlice<'_, T> {
*self
}
}
impl<T> AsUnaligned for &[T] {
type Element = T;
fn as_unaligned(&self) -> UnalignedSlice<'_, T> {
(*self).into()
}
}
impl<T, const N: usize> AsUnaligned for &[T; N] {
type Element = T;
fn as_unaligned(&self) -> UnalignedSlice<'_, T> {
(*self).into()
}
}
impl<T, const N: usize> AsUnaligned for [T; N] {
type Element = T;
fn as_unaligned(&self) -> UnalignedSlice<'_, T> {
self.into()
}
}
#[cfg(test)]
#[derive(Debug)]
pub(crate) struct Buffer<T>
where
T: bytemuck::Pod,
{
data: Vec<u8>,
len: usize,
_type: PhantomData<T>,
}
#[cfg(test)]
impl<T> Default for Buffer<T>
where
T: bytemuck::Pod,
{
fn default() -> Self {
Self {
data: vec![0u8; 1],
len: 0,
_type: PhantomData,
}
}
}
#[cfg(test)]
impl<T> Buffer<T>
where
T: bytemuck::Pod,
{
pub(crate) fn new(x: &[T]) -> Self {
let mut this = Self::default();
this.copy(x);
this
}
pub(crate) fn copy(&mut self, x: &[T]) {
let bytes = std::mem::size_of_val(x);
self.data.resize(bytes.checked_add(1).unwrap(), 0u8);
let dst = unsafe { self.data.as_mut_ptr().add(1) };
unsafe {
std::ptr::copy_nonoverlapping::<u8>(
bytemuck::must_cast_slice::<T, u8>(x).as_ptr(),
dst,
bytes,
);
}
self.len = x.len();
}
pub(crate) fn as_unaligned(&self) -> UnalignedSlice<'_, T> {
unsafe { UnalignedSlice::new(self.data.as_ptr().add(1).cast::<T>(), self.len) }
}
}