#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] pub struct SlotId { idx: u32, genr: u32, } impl SlotId { pub(crate) fn slot(self) -> u32 { self.idx } /// A stable, collision-free `u64` encoding of this id -- for a caller /// (accesskit's `NodeId`, today) that wants a flat integer key rather /// than the two `u32`s. `idx` is offset by one so no real id ever /// encodes to 0, which callers can then reserve for their own /// out-of-band root/window node. pub fn as_u64(&self) -> u64 { ((self.idx as u64) + 1) << 32 | self.genr as u64 } } pub struct SlotVec { data: Vec<(u32, Option)>, free: Vec, len: usize, } impl SlotVec { pub fn new() -> Self { Self { data: Default::default(), free: Default::default(), len: 0, } } pub fn add(&mut self, x: T) -> SlotId { let id = if let Some(idx) = self.free.pop() { let (genr, data) = &mut self.data[idx as usize]; *data = Some(x); SlotId { idx, genr: *genr } } else { let idx = self.data.len() as u32; let genr = 0; self.data.push((genr, Some(x))); SlotId { idx, genr } }; self.len += 1; id } pub fn free(&mut self, id: SlotId) { let _ = self.remove(id); } pub fn remove(&mut self, id: SlotId) -> Option { self.remove_inner(id, true) } pub fn remove_unrecycled(&mut self, id: SlotId) -> Option { self.remove_inner(id, false) } fn remove_inner(&mut self, id: SlotId, recycle: bool) -> Option { let (genr, data) = &mut self.data[id.idx as usize]; if *genr != id.genr { return None; } *genr += 1; let value = data.take()?; self.len -= 1; if recycle { self.free.push(id.idx); } Some(value) } pub fn get(&self, id: SlotId) -> Option<&T> { let slot = &self.data[id.idx as usize]; if slot.0 != id.genr { return None; } slot.1.as_ref() } pub fn get_mut(&mut self, id: SlotId) -> Option<&mut T> { let slot = &mut self.data[id.idx as usize]; if slot.0 != id.genr { return None; } slot.1.as_mut() } pub fn len(&self) -> usize { self.len } pub fn is_empty(&self) -> bool { self.len() == 0 } pub fn values_mut(&mut self) -> impl Iterator { self.data.iter_mut().filter_map(|(_, value)| value.as_mut()) } pub fn capacity(&self) -> usize { self.data.len() } } impl Default for SlotVec { fn default() -> Self { Self::new() } }