use core::fmt;
use core::ptr;
use kevy_hash::KevyHash;
use crate::map::{EMPTY, KevyMap};
pub struct IntoIter<K, V> {
map: KevyMap<K, V>,
pos: usize,
}
impl<K, V> IntoIter<K, V> {
pub(crate) fn new(map: KevyMap<K, V>) -> Self {
IntoIter { map, pos: 0 }
}
}
impl<K, V> Iterator for IntoIter<K, V> {
type Item = (K, V);
fn next(&mut self) -> Option<(K, V)> {
while self.pos < self.map.cap {
let i = self.pos;
self.pos += 1;
let meta = unsafe { self.map.metadata_ptr.as_ptr().add(i) };
if unsafe { *meta } & 0x80 == 0 {
unsafe { *meta = EMPTY };
self.map.occupied -= 1;
return Some(unsafe { ptr::read(self.map.slots_ptr.as_ptr().add(i).cast()) });
}
}
None
}
fn size_hint(&self) -> (usize, Option<usize>) {
(self.map.occupied, Some(self.map.occupied))
}
}
impl<K, V> ExactSizeIterator for IntoIter<K, V> {}
impl<K: fmt::Debug, V: fmt::Debug> fmt::Debug for IntoIter<K, V> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("IntoIter").field("remaining", &self.map.occupied).finish_non_exhaustive()
}
}
impl<K, V> IntoIterator for KevyMap<K, V> {
type Item = (K, V);
type IntoIter = IntoIter<K, V>;
fn into_iter(self) -> IntoIter<K, V> {
IntoIter::new(self)
}
}
impl<K, V> PartialEq for KevyMap<K, V>
where
K: KevyHash + Eq,
V: PartialEq,
{
fn eq(&self, other: &Self) -> bool {
self.len() == other.len() && self.iter().all(|(k, v)| other.get(k) == Some(v))
}
}
impl<K: KevyHash + Eq, V: Eq> Eq for KevyMap<K, V> {}