use core::ops::Range;
use slotmap::{Key, SlotMap};
extern crate alloc;
use alloc::vec::Vec;
use crate::SliceContainer;
use super::{Slice, iter::*};
#[derive(Default, Debug, Clone)]
pub struct SliceMap<K, V>
where K: Key,
{
pub(crate) items: Vec<V>, pub(crate) slices: SlotMap<K, Slice>, }
impl<K, V> SliceMap<K, V>
where K: Key
{
pub fn new() -> Self {
Self {
items: Vec::new(),
slices: SlotMap::with_key(),
}
}
pub fn with_capacity(cap: usize) -> Self {
Self {
items: Vec::with_capacity(cap),
slices: SlotMap::with_key(),
}
}
pub fn clear(&mut self) {
self.items.clear();
self.slices.clear();
}
pub fn items(&self) -> &[V] {
&self.items
}
pub fn add_items<ITER>(&mut self, new_items: ITER) -> K
where
ITER: IntoIterator<Item = V>,
{
let start: u32 = self.items.len().try_into().unwrap();
self.items.extend(new_items);
let end: u32 = self.items.len().try_into().unwrap();
self.slices.insert(start..end)
}
pub fn items_len(&self) -> usize {
self.items.len()
}
pub fn slices_len(&self) -> usize {
self.slices.len()
}
pub fn get_slice(&self, key: K) -> Option<&[V]> {
let range = self.slices.get(key)?;
self.items.get(Range {
start: range.start as usize,
end: range.end as usize,
})
}
pub fn iter_slices(&self) -> SliceIter<K, V, Self> {
SliceIter {
slice_map: &self,
slices: self.slices.values(),
type_data: Default::default(),
}
}
pub fn iter_keys_and_slices(&self) -> KeySliceIter<K, V, Self> {
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<Slice> {
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)
}
}