use super::{IdOrdItem, RefMut, tables::IdOrdMapTables};
use crate::support::{
alloc::Global, borrow::DormantMutRef, btree_table, item_set::ItemSet,
};
use core::{hash::Hash, iter::FusedIterator};
#[derive(Clone, Debug)]
pub struct Iter<'a, T: IdOrdItem> {
items: &'a ItemSet<T, Global>,
iter: btree_table::Iter<'a>,
}
impl<'a, T: IdOrdItem> Iter<'a, T> {
pub(super) fn new(
items: &'a ItemSet<T, Global>,
tables: &'a IdOrdMapTables,
) -> Self {
Self { items, iter: tables.key_to_item.iter() }
}
}
impl<'a, T: IdOrdItem> Iterator for Iter<'a, T> {
type Item = &'a T;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
let index = self.iter.next()?;
Some(&self.items[index])
}
}
impl<T: IdOrdItem> ExactSizeIterator for Iter<'_, T> {
#[inline]
fn len(&self) -> usize {
self.iter.len()
}
}
impl<T: IdOrdItem> FusedIterator for Iter<'_, T> {}
#[derive(Debug)]
pub struct IterMut<'a, T: IdOrdItem>
where
T::Key<'a>: Hash,
{
items: &'a mut ItemSet<T, Global>,
tables: &'a IdOrdMapTables,
iter: btree_table::Iter<'a>,
}
impl<'a, T: IdOrdItem> IterMut<'a, T>
where
T::Key<'a>: Hash,
{
pub(super) fn new(
items: &'a mut ItemSet<T, Global>,
tables: &'a IdOrdMapTables,
) -> Self {
Self { items, tables, iter: tables.key_to_item.iter() }
}
}
impl<'a, T: IdOrdItem + 'a> Iterator for IterMut<'a, T>
where
T::Key<'a>: Hash,
{
type Item = RefMut<'a, T>;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
let index = self.iter.next()?;
let item = &mut self.items[index];
let item = unsafe { core::mem::transmute::<&mut T, &'a mut T>(item) };
let (hash, dormant) = {
let (item, dormant) = DormantMutRef::new(item);
let hash = self.tables.make_hash(item);
(hash, dormant)
};
let item = unsafe { dormant.awaken() };
Some(RefMut::new(self.tables.state().clone(), hash, item))
}
}
impl<'a, T: IdOrdItem + 'a> ExactSizeIterator for IterMut<'a, T>
where
T::Key<'a>: Hash,
{
#[inline]
fn len(&self) -> usize {
self.iter.len()
}
}
impl<'a, T: IdOrdItem + 'a> FusedIterator for IterMut<'a, T> where
T::Key<'a>: Hash
{
}
#[derive(Debug)]
pub struct IntoIter<T: IdOrdItem> {
items: ItemSet<T, Global>,
iter: btree_table::IntoIter,
}
impl<T: IdOrdItem> IntoIter<T> {
pub(super) fn new(
items: ItemSet<T, Global>,
tables: IdOrdMapTables,
) -> Self {
Self { items, iter: tables.key_to_item.into_iter() }
}
}
impl<T: IdOrdItem> Iterator for IntoIter<T> {
type Item = T;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
let index = self.iter.next()?;
let next = self
.items
.remove(index)
.unwrap_or_else(|| panic!("index {index} not found in items"));
Some(next)
}
}