use std::usize; pub struct Index { index: u32, _marker: std::marker::PhantomData, } impl Eq for Index {} impl PartialEq for Index { fn eq(&self, other: &Self) -> bool { self.index == other.index } } impl std::hash::Hash for Index { fn hash(&self, state: &mut H) { self.index.hash(state); } } impl Clone for Index { fn clone(&self) -> Self { Self { index: self.index, _marker: self._marker, } } } impl Copy for Index {} impl std::fmt::Debug for Index { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "Index({})", self.index) } } impl Index { pub const fn new(index: u32) -> Self { Self { index, _marker: std::marker::PhantomData, } } pub const fn index(self) -> usize { self.index as usize } pub fn push_new(vector: &mut Vec, value: T) -> Index { let index = Self::new(vector.len() as _); vector.push(value); index } pub const fn as_slice(self) -> Slice { Slice::new(self.index, 1) } } #[derive(PartialEq, Eq)] pub struct Slice { length: u16, start: u32, _marker: std::marker::PhantomData, } impl Clone for Slice { fn clone(&self) -> Self { Self { start: self.start, length: self.length, _marker: self._marker, } } } impl Copy for Slice {} impl std::fmt::Debug for Slice { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "Slice(start = {}, length = {})", self.start, self.length) } } impl Default for Slice { fn default() -> Self { Self::empty() } } impl Slice { pub const fn empty() -> Self { Self::new(0, 0) } pub const fn new(start: u32, length: u16) -> Self { Self { start, length, _marker: std::marker::PhantomData, } } pub fn extend_new(vector: &mut Vec, values: I) -> Slice where I: IntoIterator, { let start = vector.len() as u32; vector.extend(values); let end = vector.len() as u32; Self::new(start, (end - start) as u16) } pub const fn len(&self) -> usize { self.length as _ } pub const fn start(&self) -> usize { self.start as _ } pub const fn is_empty(&self) -> bool { self.length == 0 } pub const fn indices(&self) -> std::ops::Range { self.start as usize..(self.start as usize + self.length as usize) } pub fn into_iter(&self) -> impl Iterator> { self.indices().map(|i| Index::new(i as _)) } } #[derive(PartialEq, Eq)] pub struct EitherIndex { index: u32, _marker: std::marker::PhantomData<(T, U)>, } impl Clone for EitherIndex { fn clone(&self) -> Self { Self { index: self.index, _marker: self._marker, } } } impl Copy for EitherIndex {} impl std::fmt::Debug for EitherIndex { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "Index({})", self.index) } } impl EitherIndex { const MASK: u32 = 1 << 31; pub const fn from_left(input: Index) -> Self { assert!(input.index & Self::MASK == 0); Self { index: input.index, _marker: std::marker::PhantomData, } } pub const fn from_right(input: Index) -> Self { assert!(input.index & Self::MASK == 0); Self { index: input.index | Self::MASK, _marker: std::marker::PhantomData, } } pub const fn split(self) -> Result, Index> { if self.index & Self::MASK == 0 { Ok(Index::new(self.index)) } else { Err(Index::new(self.index ^ Self::MASK)) } } }