use core::marker::PhantomData;
use core::mem::size_of;
use crate::offset::DefaultTargetSize;
use crate::offset::TargetSize;
use crate::r#ref::Ref;
use crate::ZeroCopy;
#[derive(Debug, ZeroCopy)]
#[repr(C)]
#[zero_copy(crate)]
pub struct Slice<T, O: TargetSize = DefaultTargetSize> {
offset: O,
len: O,
#[zero_copy(ignore)]
_marker: PhantomData<T>,
}
impl<T, O: TargetSize> Slice<T, O> {
pub fn new(offset: usize, len: usize) -> Self {
let Some(offset) = O::from_usize(offset) else {
panic!(
"Slice offset {offset} not in the legal range of 0-{}",
O::MAX
);
};
let Some(len) = O::from_usize(len) else {
panic!("Slice length {len} not in the legal range of 0-{}", O::MAX);
};
Self {
offset,
len,
_marker: PhantomData,
}
}
#[inline]
pub fn offset(&self) -> usize {
self.offset.as_usize()
}
#[inline]
pub fn len(&self) -> usize {
self.len.as_usize()
}
pub fn is_empty(&self) -> bool {
self.len.is_zero()
}
pub fn get(&self, index: usize) -> Option<Ref<T, O>>
where
T: ZeroCopy,
{
if index >= self.len() {
return None;
}
let ptr = self
.offset()
.wrapping_add(size_of::<T>().wrapping_mul(index));
Some(Ref::new(ptr))
}
}
impl<T, O: TargetSize> Clone for Slice<T, O> {
fn clone(&self) -> Self {
*self
}
}
impl<T, O: TargetSize> Copy for Slice<T, O> {}