use std::mem::MaybeUninit;
use crate::indexer::Occupied;
use crate::Slab;
#[derive(Debug)]
pub struct ValuesMut<'a, T> {
occupied: Occupied<'a>,
entries: core::slice::IterMut<'a, MaybeUninit<T>>,
prev_index: Option<usize>,
}
impl<'a, T> ValuesMut<'a, T> {
pub(crate) fn new(slab: &'a mut Slab<T>) -> Self {
let occupied = slab.index.occupied();
let entries = slab.entries.iter_mut();
Self {
occupied,
entries,
prev_index: None,
}
}
}
impl<'a, T> Iterator for ValuesMut<'a, T> {
type Item = &'a mut T;
fn next(&mut self) -> Option<Self::Item> {
let index = self.occupied.next()?;
let skip = match self.prev_index {
None => 0,
Some(prev_index) => index - prev_index - 1,
};
self.prev_index = Some(index);
advance_by(&mut self.entries, skip);
self.entries.next().map(|t| unsafe { t.assume_init_mut() })
}
}
fn advance_by(iter: &mut impl Iterator, n: usize) {
for _ in 0..n {
iter.next();
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn iter_mut() {
let mut slab = crate::Slab::new();
slab.insert(1);
let key = slab.insert(2);
slab.insert(3);
slab.remove(key);
let mut iter = ValuesMut::new(&mut slab);
assert_eq!(iter.next(), Some(&mut 1));
assert_eq!(iter.next(), Some(&mut 3));
assert_eq!(iter.next(), None);
}
}