use core::marker::PhantomData;
use crate::{
Field,
type_lists::{
ConsSet,
GetPtr,
GetStride,
SculptSlice,
TupleSet,
},
};
#[derive(Debug, PartialEq, Eq)]
pub struct LensSlice<'a, T>
where
T: TupleSet,
{
storage: T::ConsSlice,
len: usize,
_phantom: PhantomData<&'a ()>,
}
impl<T> Clone for LensSlice<'_, T>
where
T: TupleSet,
T::ConsSlice: Clone,
{
#[inline]
fn clone(&self) -> Self {
Self {
storage: self.storage.clone(),
len: self.len,
_phantom: PhantomData,
}
}
}
impl<T> Copy for LensSlice<'_, T>
where
T: TupleSet,
T::ConsSlice: Copy,
{
}
impl<'a, T> LensSlice<'a, T>
where
T: TupleSet,
{
#[inline]
pub(crate) const fn new(storage: T::ConsSlice, len: usize) -> Self {
Self {
storage,
len,
_phantom: PhantomData,
}
}
#[expect(clippy::type_complexity, reason = "help")]
#[inline]
pub fn split<Lhs, Indices>(
self,
) -> (
LensSlice<'a, Lhs>,
LensSlice<
'a,
<<T::ConsSlice as SculptSlice<Lhs::ConsSlice, Indices>>::Remainder as ConsSet>::Tuple,
>,
)
where
Lhs: TupleSet,
T::ConsSlice: SculptSlice<Lhs::ConsSlice, Indices>,
<T::ConsSlice as SculptSlice<Lhs::ConsSlice, Indices>>::Remainder: ConsSet<
Tuple: TupleSet<
ConsSlice = <T::ConsSlice as SculptSlice<Lhs::ConsSlice, Indices>>::Remainder,
>,
>,
{
let (lhs_storage, rem_storage) = self.storage.sculpt_slice();
(
LensSlice {
storage: lhs_storage,
len: self.len,
_phantom: PhantomData,
},
LensSlice {
storage: rem_storage,
len: self.len,
_phantom: PhantomData,
},
)
}
#[inline]
pub fn as_ptr<Elt, Index>(&self) -> *const Elt::Type
where
Elt: Field + 'static,
T::ConsSlice: GetPtr<Elt, Index>,
{
self.storage.get_ptr().as_ptr()
}
#[inline]
#[must_use]
pub fn get<Elt, Index>(&self, i: usize) -> Option<&'a Elt::Type>
where
Elt: Field + 'static,
T::ConsSlice: GetPtr<Elt, Index> + GetStride<Elt, Index>,
{
if i < self.len {
Some(unsafe { self.get_unchecked::<Elt, _>(i) })
} else {
None
}
}
#[inline]
#[must_use]
pub unsafe fn get_unchecked<Elt, Index>(&self, i: usize) -> &'a Elt::Type
where
Elt: Field + 'static,
T::ConsSlice: GetPtr<Elt, Index> + GetStride<Elt, Index>,
{
let base: *const Elt::Type = self.storage.get_ptr().as_ptr();
let stride = self.storage.get_stride();
unsafe { &*base.cast::<u8>().add(stride * i).cast::<Elt::Type>() }
}
#[inline]
pub const fn len(&self) -> usize {
self.len
}
#[inline]
pub fn stride<Elt, Index>(&self) -> usize
where
Elt: Field + 'static,
T::ConsSlice: GetStride<Elt, Index>,
{
self.storage.get_stride()
}
#[inline]
pub const fn is_empty(&self) -> bool {
self.len == 0
}
}