#![doc = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/readme.md"))]
#[cfg(test)]
pub(crate) mod test;
mod traits;
pub use traits::*;
mod iter;
pub use iter::*;
use core::{marker::PhantomData, ops::Range};
use slotmap::{Key, SecondaryMap, SlotMap, SparseSecondaryMap};
extern crate alloc;
use alloc::vec::Vec;
#[derive(Default, Debug, Clone)]
pub struct SliceMap<K, V, S>
where
K: Key,
S: SliceStorage<K, Range<u32>>,
{
pub(crate) items: Vec<V>, pub(crate) slices: S, type_key: PhantomData<K>,
}
impl<K, V, S> SliceMap<K, V, S>
where
K: Key,
S: SliceStorage<K, Range<u32>> + Default,
{
pub fn new() -> Self {
Self {
items: Vec::new(),
slices: S::default(),
type_key: Default::default(),
}
}
pub fn with_capacity(cap: usize) -> Self {
Self {
items: Vec::with_capacity(cap),
slices: S::default(),
type_key: Default::default(),
}
}
pub fn clear(&mut self) {
self.items.clear();
self.slices = S::default();
}
pub fn items(&self) -> &[V] {
&self.items
}
pub fn items_len(&self) -> usize {
self.items.len()
}
pub fn is_empty(&self) -> bool {
self.items.is_empty()
}
pub fn slices_len(&self) -> usize {
self.slices.iter().count()
}
pub fn get_slice(&self, key: K) -> Option<&[V]> {
let range = self.slices.get(key)?;
self.items.get(range.start as usize..range.end as usize)
}
pub fn iter_slices(&self) -> SliceIter<K, V, S> {
SliceIter {
slice_map: &self,
slices: self.slices.values(),
type_data: Default::default(),
}
}
pub fn iter_keys_and_slices(&self) -> KeySliceIter<K, V, S> {
KeySliceIter {
slice_map: &self,
slices: self.slices.iter(),
type_data: Default::default(),
}
}
pub fn iter_items(&self) -> impl Iterator<Item = &V> {
self.items.iter() }
pub fn remove_slice(&mut self, key: K) -> Option<Range<u32>> {
let removed_slice = self.slices.remove(key)?;
self.items
.drain(removed_slice.start as usize..removed_slice.end as usize);
let offset = removed_slice.end - removed_slice.start;
for slice in self.slices.values_mut() {
if slice.start >= removed_slice.end {
slice.start = u32::try_from(slice.start - offset).expect("Index out of bounds");
slice.end = u32::try_from(slice.end - offset).expect("Index out of bounds");
}
}
Some(removed_slice)
}
}
pub type SlotSliceMap<K, V> = SliceMap<K, V, SlotMap<K, Range<u32>>>;
impl<K, V> SlotSliceMap<K, V>
where
K: Key,
V: Clone, {
pub fn add_items<ITEMS>(&mut self, new_items: ITEMS) -> K
where
ITEMS: AsRef<[V]>, {
let start: u32 = self.items.len().try_into().unwrap();
self.items.extend(new_items.as_ref().iter().cloned());
let end: u32 = self.items.len().try_into().unwrap();
self.slices.insert(start..end)
}
}
pub type SecSliceMap<K, V> = SliceMap<K, V, SecondaryMap<K, Range<u32>>>;
impl<K, V> SecSliceMap<K, V>
where
K: Key,
V: Clone, {
pub fn add_items<ITEMS>(&mut self, key: K, new_items: ITEMS)
where
ITEMS: AsRef<[V]>, {
let start: u32 = self.items.len().try_into().unwrap();
self.items.extend(new_items.as_ref().iter().cloned());
let end: u32 = self.items.len().try_into().unwrap();
self.slices.insert(key, start..end);
}
}
pub type SparseSliceMap<K, V> = SliceMap<K, V, SparseSecondaryMap<K, Range<u32>>>;
impl<K, V> SparseSliceMap<K, V>
where
K: Key,
V: Clone, {
pub fn add_items<ITEMS>(&mut self, key: K, new_items: ITEMS)
where
ITEMS: AsRef<[V]>, {
let start: u32 = self.items.len().try_into().unwrap();
self.items.extend(new_items.as_ref().iter().cloned());
let end: u32 = self.items.len().try_into().unwrap();
self.slices.insert(key, start..end);
}
}