macro_rules! imp_slot_map {
(
new $($const:ident)?: $new:expr,
slots: $slots:ident,
($($value:ty)?)
) => {
#[derive(Debug, Clone)]
#[repr(transparent)]
pub struct SlotMap<T>(pub Arena<T, ()>);
pub struct VacantEntry<'a, T>(pub imp::VacantEntry<'a, T, ()>);
pub type Key = $crate::Key<usize>;
pub type Entries<'a, T> = imp::Entries<'a, T, (), DefaultVersion, usize>;
pub type EntriesMut<'a, T> = imp::EntriesMut<'a, T, (), DefaultVersion, usize>;
pub type IntoEntries<T> = imp::IntoEntries<T, (), DefaultVersion, usize>;
impl<T> VacantEntry<'_, T> {
pub fn key(&self) -> usize { self.0.key() }
pub fn insert(self, value: T) -> usize { self.0.insert(value) }
}
impl<T> Default for SlotMap<T> {
fn default() -> Self { Self::new() }
}
impl<T> SlotMap<T> {
pub $($const)? fn new() -> Self { Self($new) }
pub fn is_empty(&self) -> bool { self.0.is_empty() }
pub fn len(&self) -> usize { self.0.len() }
pub fn capacity(&self) -> usize { self.0.capacity() }
pub fn reserve(&mut self, additional: usize) { self.0.reserve(additional) }
pub fn clear(&mut self) { self.0.clear(); }
pub fn vacant_entry(&mut self) -> VacantEntry<'_, T> { VacantEntry(self.0.vacant_entry()) }
pub fn insert(&mut self, value: T) -> Key { self.0.insert(value) }
pub fn contains(&self, key: Key) -> bool { self.0.contains(key) }
pub fn remove(&mut self, key: Key) -> T { self.0.remove(key) }
pub fn try_remove(&mut self, key: Key) -> Option<T> { self.0.try_remove(key) }
pub fn delete(&mut self, key: Key) -> bool { self.0.delete(key) }
pub fn get(&self, key: Key) -> Option<&T> { self.0.get(key) }
pub fn get_mut(&mut self, key: Key) -> Option<&mut T> { self.0.get_mut(key) }
#[allow(clippy::missing_safety_doc)]
pub unsafe fn get_unchecked(&self, index: usize) -> &T { self.0.get_unchecked(index) }
#[allow(clippy::missing_safety_doc)]
pub unsafe fn get_unchecked_mut(&mut self, index: usize) -> &mut T { self.0.get_unchecked_mut(index) }
pub fn delete_all(&mut self) { self.0.delete_all() }
pub fn retain<F: FnMut(&mut T) -> bool>(&mut self, f: F) { self.0.retain(f) }
pub fn keys(&self) -> Keys<'_ $(, $value)?> { self.0.keys() }
pub fn iter(&self) -> Iter<'_, T> { self.0.iter() }
pub fn iter_mut(&mut self) -> IterMut<'_, T> { self.0.iter_mut() }
pub fn drain(&mut self) -> Drain<'_, T> { self.0.drain() }
pub fn drain_filter<F: FnMut(&mut T) -> bool>(&mut self, filter: F) -> DrainFilter<'_, T, F> { self.0.drain_filter(filter) }
pub fn entries(&self) -> Entries<'_, T> { self.0.entries() }
pub fn entries_mut(&mut self) -> EntriesMut<'_, T> { self.0.entries_mut() }
pub fn into_entries(self) -> IntoEntries<T> { self.0.into_entries() }
}
impl<T> IntoIterator for SlotMap<T> {
type IntoIter = IntoIter<T>;
type Item = T;
fn into_iter(self) -> Self::IntoIter { self.0.into_iter() }
}
impl<T> Index<Key> for SlotMap<T> {
type Output = T;
fn index(&self, key: Key) -> &Self::Output { &self.0[key] }
}
impl<T> IndexMut<Key> for SlotMap<T> {
fn index_mut(&mut self, key: Key) -> &mut Self::Output { &mut self.0[key] }
}
};
}
pub mod dense {
use core::ops::{Index, IndexMut};
use crate::{
base::dense::{self as imp, Arena},
version::DefaultVersion,
};
pub type Iter<'a, T> = core::slice::Iter<'a, T>;
pub type IterMut<'a, T> = core::slice::IterMut<'a, T>;
pub type IntoIter<T> = std::vec::IntoIter<T>;
pub type Drain<'a, T> = imp::Drain<'a, T, (), DefaultVersion>;
pub type DrainFilter<'a, T, F> = imp::DrainFilter<'a, T, (), DefaultVersion, F>;
pub type Keys<'a> = imp::Keys<'a, (), DefaultVersion, Key>;
imp_slot_map! {
new: Arena::with_ident(()),
slots: len,
()
}
}
pub mod hop {
use core::ops::{Index, IndexMut};
use crate::{
base::hop::{self as imp, Arena},
version::DefaultVersion,
};
pub type Iter<'a, T> = imp::Iter<'a, T, DefaultVersion>;
pub type IterMut<'a, T> = imp::IterMut<'a, T, DefaultVersion>;
pub type IntoIter<T> = imp::IntoIter<T, DefaultVersion>;
pub type Drain<'a, T> = imp::Drain<'a, T, DefaultVersion>;
pub type DrainFilter<'a, T, F> = imp::DrainFilter<'a, T, DefaultVersion, F>;
pub type Keys<'a, T> = imp::Keys<'a, T, (), DefaultVersion, Key>;
imp_slot_map! {
new: Arena::with_ident(()),
slots: len,
(T)
}
}
pub mod sparse {
use core::ops::{Index, IndexMut};
use crate::{
base::sparse::{self as imp, Arena},
version::DefaultVersion,
};
pub type Iter<'a, T> = imp::Iter<'a, T, DefaultVersion>;
pub type IterMut<'a, T> = imp::IterMut<'a, T, DefaultVersion>;
pub type IntoIter<T> = imp::IntoIter<T, DefaultVersion>;
pub type Drain<'a, T> = imp::Drain<'a, T, DefaultVersion>;
pub type DrainFilter<'a, T, F> = imp::DrainFilter<'a, T, DefaultVersion, F>;
pub type Keys<'a, T> = imp::Keys<'a, T, (), DefaultVersion, Key>;
imp_slot_map! {
new const: Arena::INIT,
slots: slots,
(T)
}
}