use super::*;
use crate::stk;
macro_rules! iter_methods {
($map_fn:expr) => {
#[inline]
fn next(&mut self) -> Option<Self::Item> {
self.iter.next().map($map_fn)
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
#[inline]
fn count(self) -> usize {
self.iter.count()
}
#[inline]
fn nth(&mut self, n: usize) -> Option<Self::Item> {
self.iter.nth(n).map($map_fn)
}
#[inline]
fn last(self) -> Option<Self::Item>
where
Self: Sized,
{
self.iter.last().map($map_fn)
}
};
}
pub struct Iter<'a, K, V> {
iter: core::iter::Rev<stk::Iter<'a, Bucket<K, V>>>,
}
impl<'a, K, V> Iter<'a, K, V> {
pub(super) fn new(entries: &'a Entries<K, V>) -> Self {
Self {
iter: entries.iter().rev(),
}
}
}
impl<'a, K, V> core::iter::Iterator for Iter<'a, K, V> {
type Item = (&'a K, &'a V);
iter_methods!(Bucket::as_tuple);
}
impl<'a, K, V> core::iter::DoubleEndedIterator for Iter<'a, K, V> {
#[inline]
fn next_back(&mut self) -> Option<Self::Item> {
self.iter.next_back().map(Bucket::as_tuple)
}
}
pub struct IterMut<'a, K, V> {
iter: core::iter::Rev<stk::IterMut<'a, Bucket<K, V>>>,
}
impl<'a, K, V> IterMut<'a, K, V> {
pub(super) fn new(entries: &'a mut Entries<K, V>) -> Self {
Self {
iter: entries.iter_mut().rev(),
}
}
}
impl<'a, K, V> core::iter::Iterator for IterMut<'a, K, V> {
type Item = (&'a K, &'a mut V);
iter_methods!(Bucket::as_tuple_mut);
}
impl<'a, K, V> core::iter::DoubleEndedIterator for IterMut<'a, K, V> {
#[inline]
fn next_back(&mut self) -> Option<Self::Item> {
self.iter.next_back().map(Bucket::as_tuple_mut)
}
}
pub struct Drain<'a, K: Eq, V> {
core: &'a mut Core<K, V>,
}
impl<'a, K: Eq, V> Drain<'a, K, V> {
pub(super) fn new(core: &'a mut Core<K, V>) -> Self {
Self { core }
}
}
impl<K: Eq, V> core::iter::Iterator for Drain<'_, K, V> {
type Item = (K, V);
fn next(&mut self) -> Option<Self::Item> {
self.core.pop().map(Bucket::into_tuple)
}
}
impl<K: Eq, V> core::ops::Drop for Drain<'_, K, V> {
fn drop(&mut self) {
while let Some(bucket) = self.core.pop() {
drop(bucket);
}
}
}