use std::fmt::{Debug, Display, Formatter};
use std::hash::{Hash, Hasher};
use std::iter::FusedIterator;
use std::marker::PhantomData;
use std::ops::{Index, IndexMut};
#[repr(transparent)]
pub struct Key<Tag: ?Sized> {
index: usize,
_phantom: PhantomData<Tag>,
}
impl<Tag: ?Sized> Key<Tag> {
pub const fn from_raw(index: usize) -> Self {
Key {
index,
_phantom: PhantomData,
}
}
}
impl<Tag: ?Sized> Clone for Key<Tag> {
fn clone(&self) -> Self {
*self
}
}
impl<Tag: ?Sized> Copy for Key<Tag> {}
impl<Tag: ?Sized> PartialOrd for Key<Tag> {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
Some(self.cmp(other))
}
}
impl<Tag: ?Sized> Ord for Key<Tag> {
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
self.index.cmp(&other.index)
}
}
impl<Tag: ?Sized> PartialEq for Key<Tag> {
fn eq(&self, other: &Self) -> bool {
self.index == other.index
}
}
impl<Tag: ?Sized> Eq for Key<Tag> {}
impl<Tag: ?Sized> Hash for Key<Tag> {
fn hash<H: Hasher>(&self, state: &mut H) {
self.index.hash(state);
}
}
impl<Tag: ?Sized> Debug for Key<Tag> {
fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
write!(f, "Key({})", self.index)
}
}
impl<Tag: ?Sized> Display for Key<Tag> {
fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
write!(f, "{}", self.index)
}
}
#[repr(transparent)]
pub struct SlotVec<Tag: ?Sized, Val> {
slots: Vec<Val>,
_phantom: PhantomData<Tag>,
}
impl<Tag: ?Sized, Val> SlotVec<Tag, Val> {
pub const fn new() -> Self {
Self {
slots: Vec::new(),
_phantom: PhantomData,
}
}
pub fn len(&self) -> usize {
self.slots.len()
}
pub fn is_empty(&self) -> bool {
self.slots.is_empty()
}
pub fn insert(&mut self, value: Val) -> Key<Tag> {
let key = Key::from_raw(self.slots.len());
self.slots.push(value);
key
}
pub fn insert_with_key<F>(&mut self, func: F) -> Key<Tag>
where
F: FnOnce(Key<Tag>) -> Val,
{
let key = Key::from_raw(self.slots.len());
self.slots.push((func)(key));
key
}
pub fn get(&self, key: Key<Tag>) -> Option<&Val> {
self.slots.get(key.index)
}
pub fn get_mut(&mut self, key: Key<Tag>) -> Option<&mut Val> {
self.slots.get_mut(key.index)
}
pub fn iter(
&self,
) -> impl DoubleEndedIterator<Item = (Key<Tag>, &'_ Val)> + ExactSizeIterator + FusedIterator + Clone
{
self.slots
.iter()
.enumerate()
.map(|(idx, val)| (Key::from_raw(idx), val))
}
pub fn iter_mut(
&mut self,
) -> impl DoubleEndedIterator<Item = (Key<Tag>, &'_ mut Val)> + ExactSizeIterator + FusedIterator
{
self.slots
.iter_mut()
.enumerate()
.map(|(idx, val)| (Key::from_raw(idx), val))
}
pub fn values(&self) -> std::slice::Iter<'_, Val> {
self.slots.iter()
}
pub fn values_mut(&mut self) -> std::slice::IterMut<'_, Val> {
self.slots.iter_mut()
}
pub fn keys(
&self,
) -> impl '_ + DoubleEndedIterator<Item = Key<Tag>> + ExactSizeIterator + FusedIterator + Clone
{
self.iter().map(|(key, _)| key)
}
}
impl<Tag: ?Sized, Val> Index<Key<Tag>> for SlotVec<Tag, Val> {
type Output = Val;
fn index(&self, key: Key<Tag>) -> &Self::Output {
self.get(key).unwrap()
}
}
impl<Tag: ?Sized, Val> IndexMut<Key<Tag>> for SlotVec<Tag, Val> {
fn index_mut(&mut self, key: Key<Tag>) -> &mut Self::Output {
self.get_mut(key).unwrap()
}
}
impl<Key: ?Sized, Val> Default for SlotVec<Key, Val> {
fn default() -> Self {
Self::new()
}
}
pub struct SecondarySlotVec<Tag: ?Sized, Val> {
slots: Vec<Option<Val>>,
_phantom: PhantomData<Tag>,
}
impl<Tag: ?Sized, Val> SecondarySlotVec<Tag, Val> {
pub const fn new() -> Self {
Self {
slots: Vec::new(),
_phantom: PhantomData,
}
}
pub fn len(&self) -> usize {
self.iter().count()
}
pub fn is_empty(&self) -> bool {
self.iter().next().is_none()
}
pub fn insert(&mut self, key: Key<Tag>, value: Val) -> Option<Val> {
if key.index >= self.slots.len() {
self.slots.resize_with(key.index + 1, || None);
}
self.slots[key.index].replace(value)
}
pub fn remove(&mut self, key: Key<Tag>) -> Option<Val> {
self.slots[key.index].take()
}
pub fn get(&self, key: Key<Tag>) -> Option<&Val> {
self.slots.get(key.index).and_then(|v| v.as_ref())
}
pub fn get_mut(&mut self, key: Key<Tag>) -> Option<&mut Val> {
self.slots.get_mut(key.index).and_then(|v| v.as_mut())
}
pub fn get_or_insert_with(&mut self, key: Key<Tag>, default: impl FnOnce() -> Val) -> &mut Val {
if key.index >= self.slots.len() {
self.slots.resize_with(key.index + 1, || None);
}
self.slots[key.index].get_or_insert_with(default)
}
pub fn iter(
&self,
) -> impl DoubleEndedIterator<Item = (Key<Tag>, &'_ Val)> + FusedIterator + Clone {
self.slots
.iter()
.enumerate()
.filter_map(|(idx, opt_val)| Some((Key::from_raw(idx), opt_val.as_ref()?)))
}
pub fn iter_mut(
&mut self,
) -> impl DoubleEndedIterator<Item = (Key<Tag>, &'_ mut Val)> + FusedIterator {
self.slots
.iter_mut()
.enumerate()
.filter_map(|(idx, opt_val)| Some((Key::from_raw(idx), opt_val.as_mut()?)))
}
pub fn values(&self) -> impl DoubleEndedIterator<Item = &'_ Val> + FusedIterator + Clone {
self.slots.iter().filter_map(Option::as_ref)
}
pub fn values_mut(&mut self) -> impl DoubleEndedIterator<Item = &'_ mut Val> + FusedIterator {
self.slots.iter_mut().filter_map(Option::as_mut)
}
pub fn keys(&self) -> impl '_ + DoubleEndedIterator<Item = Key<Tag>> + FusedIterator + Clone {
self.iter().map(|(key, _)| key)
}
}
impl<Tag: ?Sized, Val> Default for SecondarySlotVec<Tag, Val> {
fn default() -> Self {
Self::new()
}
}
impl<Tag: ?Sized, Val> Clone for SecondarySlotVec<Tag, Val>
where
Val: Clone,
{
fn clone(&self) -> Self {
Self {
slots: self.slots.clone(),
_phantom: PhantomData,
}
}
}
impl<Tag: ?Sized, Val> Index<Key<Tag>> for SecondarySlotVec<Tag, Val> {
type Output = Val;
fn index(&self, key: Key<Tag>) -> &Self::Output {
self.get(key).unwrap()
}
}
impl<Tag: ?Sized, Val> IndexMut<Key<Tag>> for SecondarySlotVec<Tag, Val> {
fn index_mut(&mut self, key: Key<Tag>) -> &mut Self::Output {
self.get_mut(key).unwrap()
}
}
impl<Tag: ?Sized, Val> FromIterator<(Key<Tag>, Val)> for SecondarySlotVec<Tag, Val> {
fn from_iter<T: IntoIterator<Item = (Key<Tag>, Val)>>(iter: T) -> Self {
let mut map = SecondarySlotVec::new();
for (key, val) in iter {
map.insert(key, val);
}
map
}
}