use core::ops::{Range, RangeTo, RangeToInclusive};
use crate::{SSlice, Sentinel};
pub trait SliceIndex<T: Sentinel> {
type Output: ?Sized;
unsafe fn index_unchecked(self, slice: &SSlice<T>) -> &Self::Output;
unsafe fn index_unchecked_mut(self, slice: &mut SSlice<T>) -> &mut Self::Output;
}
impl<T: Sentinel> SliceIndex<T> for usize {
type Output = T;
#[inline(always)]
unsafe fn index_unchecked(self, slice: &SSlice<T>) -> &Self::Output {
unsafe { &*slice.as_ptr().add(self) }
}
#[inline(always)]
unsafe fn index_unchecked_mut(self, slice: &mut SSlice<T>) -> &mut Self::Output {
unsafe { &mut *slice.as_mut_ptr().add(self) }
}
}
impl<T: Sentinel> SliceIndex<T> for Range<usize> {
type Output = [T];
#[inline(always)]
unsafe fn index_unchecked(self, slice: &SSlice<T>) -> &Self::Output {
unsafe {
core::slice::from_raw_parts(
slice.as_ptr().add(self.start),
self.end.wrapping_sub(self.start),
)
}
}
#[inline(always)]
unsafe fn index_unchecked_mut(self, slice: &mut SSlice<T>) -> &mut Self::Output {
unsafe {
core::slice::from_raw_parts_mut(
slice.as_mut_ptr().add(self.start),
self.end.wrapping_sub(self.start),
)
}
}
}
impl<T: Sentinel> SliceIndex<T> for RangeTo<usize> {
type Output = [T];
#[inline(always)]
unsafe fn index_unchecked(self, slice: &SSlice<T>) -> &Self::Output {
unsafe { core::slice::from_raw_parts(slice.as_ptr(), self.end) }
}
#[inline(always)]
unsafe fn index_unchecked_mut(self, slice: &mut SSlice<T>) -> &mut Self::Output {
unsafe { core::slice::from_raw_parts_mut(slice.as_mut_ptr(), self.end) }
}
}
impl<T: Sentinel> SliceIndex<T> for RangeToInclusive<usize> {
type Output = [T];
#[inline(always)]
unsafe fn index_unchecked(self, slice: &SSlice<T>) -> &Self::Output {
unsafe { core::slice::from_raw_parts(slice.as_ptr(), self.end.wrapping_add(1)) }
}
#[inline(always)]
unsafe fn index_unchecked_mut(self, slice: &mut SSlice<T>) -> &mut Self::Output {
unsafe { core::slice::from_raw_parts_mut(slice.as_mut_ptr(), self.end.wrapping_add(1)) }
}
}