use std::sync::Arc;
pub(crate) enum DenseArray<T: Copy> {
Owned(Vec<T>),
ZeroCopy {
_backing: Arc<rkyv::util::AlignedVec>,
ptr: *const T,
len: usize,
},
}
unsafe impl<T: Copy + Send> Send for DenseArray<T> {}
unsafe impl<T: Copy + Sync> Sync for DenseArray<T> {}
impl<T: Copy> DenseArray<T> {
pub unsafe fn zero_copy(
backing: Arc<rkyv::util::AlignedVec>,
ptr: *const T,
len: usize,
) -> Self {
Self::ZeroCopy {
_backing: backing,
ptr,
len,
}
}
pub fn len(&self) -> usize {
match self {
Self::Owned(v) => v.len(),
Self::ZeroCopy { len, .. } => *len,
}
}
pub fn is_empty(&self) -> bool {
self.len() == 0
}
pub fn to_vec(&self) -> Vec<T> {
match self {
Self::Owned(v) => v.clone(),
Self::ZeroCopy { ptr, len, .. } => {
let slice = unsafe { std::slice::from_raw_parts(*ptr, *len) };
slice.to_vec()
}
}
}
}
impl<T: Copy> std::ops::Deref for DenseArray<T> {
type Target = [T];
fn deref(&self) -> &[T] {
match self {
Self::Owned(v) => v,
Self::ZeroCopy { ptr, len, .. } => unsafe { std::slice::from_raw_parts(*ptr, *len) },
}
}
}
impl<T: Copy> Clone for DenseArray<T> {
fn clone(&self) -> Self {
Self::Owned(self.to_vec())
}
}
impl<T: Copy + std::fmt::Debug> std::fmt::Debug for DenseArray<T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Owned(v) => write!(f, "DenseArray::Owned({} elements)", v.len()),
Self::ZeroCopy { len, .. } => write!(f, "DenseArray::ZeroCopy({len} elements)"),
}
}
}
impl<T: Copy> Default for DenseArray<T> {
fn default() -> Self {
Self::Owned(Vec::new())
}
}
impl<T: Copy> From<Vec<T>> for DenseArray<T> {
fn from(v: Vec<T>) -> Self {
Self::Owned(v)
}
}