This commit is contained in:
Richard Feldman 2024-10-18 22:32:41 -04:00
parent e947cd78b9
commit 98535bfbce
No known key found for this signature in database
GPG key ID: 5DE4EE30BB738EDF
28 changed files with 6508 additions and 337 deletions

View file

@ -1,7 +1,31 @@
use core::{fmt, marker::PhantomData, ops::Range};
use core::{
fmt,
marker::PhantomData,
num::{NonZeroU16, NonZeroUsize},
ops::Range,
};
use crate::soa_index::Index;
#[derive(PartialEq, Eq, PartialOrd, Ord)]
pub struct NonEmptySlice<T> {
inner: Slice<T>,
}
impl<T> fmt::Debug for NonEmptySlice<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.inner.fmt(f)
}
}
impl<T> Copy for NonEmptySlice<T> {}
impl<T> Clone for NonEmptySlice<T> {
fn clone(&self) -> Self {
*self
}
}
/// A slice into an array of values, based
/// on an offset into the array rather than a pointer.
///
@ -87,13 +111,6 @@ impl<T> Slice<T> {
}
}
pub fn at(&self, i: usize) -> Index<T> {
Index {
index: self.start + i as u32,
_marker: PhantomData,
}
}
pub const fn new(start: u32, length: u16) -> Self {
Self {
start,
@ -149,3 +166,72 @@ impl<T> ExactSizeIterator for SliceIterator<T> {}
pub trait GetSlice<T> {
fn get_slice(&self, slice: Slice<T>) -> &[T];
}
impl<T> NonEmptySlice<T> {
pub const fn start(self) -> u32 {
self.inner.start()
}
pub fn advance(&mut self, amount: u32) {
self.inner.advance(amount);
}
pub fn get_slice<'a>(&self, elems: &'a [T]) -> &'a [T] {
self.inner.get_slice(elems)
}
pub fn get_slice_mut<'a>(&self, elems: &'a mut [T]) -> &'a mut [T] {
self.inner.get_slice_mut(elems)
}
#[inline(always)]
pub const fn indices(&self) -> Range<usize> {
self.inner.indices()
}
pub const fn len(&self) -> NonZeroUsize {
// Safety: we only accept a nonzero length on construction
unsafe { NonZeroUsize::new_unchecked(self.inner.len()) }
}
pub const fn new(start: u32, length: NonZeroU16) -> Self {
Self {
inner: Slice {
start,
length: length.get(),
_marker: PhantomData,
},
}
}
pub const unsafe fn new_unchecked(start: u32, length: u16) -> Self {
Self {
inner: Slice {
start,
length,
_marker: PhantomData,
},
}
}
pub const fn from_slice(slice: Slice<T>) -> Option<Self> {
// Using a match here because Option::map is not const
match NonZeroU16::new(slice.length) {
Some(len) => Some(Self::new(slice.start, len)),
None => None,
}
}
pub const unsafe fn from_slice_unchecked(slice: Slice<T>) -> Self {
Self::new(slice.start, NonZeroU16::new_unchecked(slice.length))
}
}
impl<T> IntoIterator for NonEmptySlice<T> {
type Item = Index<T>;
type IntoIter = SliceIterator<T>;
fn into_iter(self) -> Self::IntoIter {
self.inner.into_iter()
}
}