use crate::vec::IndexVec; use crate::Idx; use std::fmt::{Debug, Formatter}; use std::marker::PhantomData; use std::ops::{Index, IndexMut, Range}; /// A view into contiguous `T`s, indexed by `I` rather than by `usize`. #[derive(PartialEq, Eq, Hash)] #[repr(transparent)] pub struct IndexSlice { index: PhantomData, pub raw: [T], } impl IndexSlice { #[inline] pub const fn empty() -> &'static Self { Self::from_raw(&[]) } #[inline] pub const fn from_raw(raw: &[T]) -> &Self { let ptr: *const [T] = raw; #[allow(unsafe_code)] // SAFETY: `IndexSlice` is `repr(transparent)` over a normal slice unsafe { &*(ptr as *const Self) } } #[inline] pub fn from_raw_mut(raw: &mut [T]) -> &mut Self { let ptr: *mut [T] = raw; #[allow(unsafe_code)] // SAFETY: `IndexSlice` is `repr(transparent)` over a normal slice unsafe { &mut *(ptr as *mut Self) } } #[inline] pub const fn first(&self) -> Option<&T> { self.raw.first() } #[inline] pub const fn len(&self) -> usize { self.raw.len() } #[inline] pub const fn is_empty(&self) -> bool { self.raw.is_empty() } #[inline] pub fn iter(&self) -> std::slice::Iter<'_, T> { self.raw.iter() } /// Returns an iterator over the indices #[inline] pub fn indices( &self, ) -> impl DoubleEndedIterator + ExactSizeIterator + Clone + 'static { (0..self.len()).map(|n| I::new(n)) } #[inline] pub fn iter_enumerated( &self, ) -> impl DoubleEndedIterator + ExactSizeIterator + '_ { self.raw.iter().enumerate().map(|(n, t)| (I::new(n), t)) } #[inline] pub fn iter_mut(&mut self) -> std::slice::IterMut<'_, T> { self.raw.iter_mut() } #[inline] pub fn last_index(&self) -> Option { self.len().checked_sub(1).map(I::new) } #[inline] pub fn swap(&mut self, a: I, b: I) { self.raw.swap(a.index(), b.index()); } #[inline] pub fn get(&self, index: I) -> Option<&T> { self.raw.get(index.index()) } #[inline] pub fn get_mut(&mut self, index: I) -> Option<&mut T> { self.raw.get_mut(index.index()) } #[inline] pub fn binary_search(&self, value: &T) -> Result where T: Ord, { match self.raw.binary_search(value) { Ok(i) => Ok(Idx::new(i)), Err(i) => Err(Idx::new(i)), } } } impl Debug for IndexSlice where I: Idx, T: Debug, { fn fmt(&self, fmt: &mut Formatter<'_>) -> std::fmt::Result { std::fmt::Debug::fmt(&self.raw, fmt) } } impl Index for IndexSlice { type Output = T; #[inline] fn index(&self, index: I) -> &T { &self.raw[index.index()] } } impl Index> for IndexSlice { type Output = [T]; #[inline] fn index(&self, range: Range) -> &[T] { &self.raw[range.start.index()..range.end.index()] } } impl IndexMut for IndexSlice { #[inline] fn index_mut(&mut self, index: I) -> &mut T { &mut self.raw[index.index()] } } impl IndexMut> for IndexSlice { #[inline] fn index_mut(&mut self, range: Range) -> &mut [T] { &mut self.raw[range.start.index()..range.end.index()] } } impl<'a, I: Idx, T> IntoIterator for &'a IndexSlice { type IntoIter = std::slice::Iter<'a, T>; type Item = &'a T; #[inline] fn into_iter(self) -> std::slice::Iter<'a, T> { self.raw.iter() } } impl<'a, I: Idx, T> IntoIterator for &'a mut IndexSlice { type IntoIter = std::slice::IterMut<'a, T>; type Item = &'a mut T; #[inline] fn into_iter(self) -> std::slice::IterMut<'a, T> { self.raw.iter_mut() } } impl ToOwned for IndexSlice { type Owned = IndexVec; fn to_owned(&self) -> IndexVec { IndexVec::from_raw(self.raw.to_owned()) } fn clone_into(&self, target: &mut IndexVec) { self.raw.clone_into(&mut target.raw); } } impl Default for &IndexSlice { #[inline] fn default() -> Self { IndexSlice::from_raw(Default::default()) } } impl Default for &mut IndexSlice { #[inline] fn default() -> Self { IndexSlice::from_raw_mut(Default::default()) } } // Whether `IndexSlice` is `Send` depends only on the data, // not the phantom data. #[allow(unsafe_code)] unsafe impl Send for IndexSlice where T: Send {}