use std::pin;
#[repr(transparent)]
pub struct Slice<T> {
entries: pin::Pin<Box<[T]>>,
}
impl<T> Slice<T> {
#[inline]
pub fn get(&self, index: usize) -> Option<pin::Pin<&T>> {
let entry = self.entries.as_ref().get_ref().get(index)?;
Some(unsafe { pin::Pin::new_unchecked(entry) })
}
#[inline]
pub fn get_mut(&mut self, index: usize) -> Option<pin::Pin<&mut T>> {
if index >= self.entries.len() {
return None;
}
Some(unsafe {
self.entries
.as_mut()
.map_unchecked_mut(|entries| &mut entries[index])
})
}
pub fn iter<'a>(
&'a self,
) -> impl DoubleEndedIterator<Item = pin::Pin<&'a T>> + ExactSizeIterator + 'a
where
T: 'a,
{
self.entries.as_ref().get_ref().iter().map(|entry| {
unsafe { pin::Pin::new_unchecked(entry) }
})
}
#[inline]
pub fn len(&self) -> usize {
self.entries.len()
}
#[inline]
pub fn is_empty(&self) -> bool {
self.entries.is_empty()
}
}
impl<T> From<Box<[T]>> for Slice<T> {
fn from(entries: Box<[T]>) -> Self {
Self {
entries: Box::into_pin(entries),
}
}
}
impl<T> FromIterator<T> for Slice<T> {
fn from_iter<I: IntoIterator<Item = T>>(entries: I) -> Self {
entries.into_iter().collect::<Box<[_]>>().into()
}
}