iddqd/id_hash_map/
iter.rs

1use super::{RefMut, tables::IdHashMapTables};
2use crate::{
3    DefaultHashBuilder, IdHashItem,
4    support::{
5        alloc::{AllocWrapper, Allocator, Global},
6        item_set::ItemSet,
7    },
8};
9use core::{hash::BuildHasher, iter::FusedIterator};
10use hashbrown::hash_map;
11
12/// An iterator over the elements of a [`IdHashMap`] by shared reference.
13/// Created by [`IdHashMap::iter`].
14///
15/// Similar to [`HashMap`], the iteration order is arbitrary and not guaranteed
16/// to be stable.
17///
18/// [`IdHashMap`]: crate::IdHashMap
19/// [`IdHashMap::iter`]: crate::IdHashMap::iter
20/// [`HashMap`]: std::collections::HashMap
21#[derive(Clone, Debug, Default)]
22pub struct Iter<'a, T: IdHashItem> {
23    inner: hash_map::Values<'a, usize, T>,
24}
25
26impl<'a, T: IdHashItem> Iter<'a, T> {
27    pub(crate) fn new<A: Allocator>(items: &'a ItemSet<T, A>) -> Self {
28        Self { inner: items.values() }
29    }
30}
31
32impl<'a, T: IdHashItem> Iterator for Iter<'a, T> {
33    type Item = &'a T;
34
35    #[inline]
36    fn next(&mut self) -> Option<Self::Item> {
37        self.inner.next()
38    }
39}
40
41impl<T: IdHashItem> ExactSizeIterator for Iter<'_, T> {
42    #[inline]
43    fn len(&self) -> usize {
44        self.inner.len()
45    }
46}
47
48// hash_map::Iter is a FusedIterator, so Iter is as well.
49impl<T: IdHashItem> FusedIterator for Iter<'_, T> {}
50
51/// An iterator over the elements of a [`IdHashMap`] by mutable reference.
52/// Created by [`IdHashMap::iter_mut`].
53///
54/// This iterator returns [`RefMut`] instances.
55///
56/// Similar to [`HashMap`], the iteration order is arbitrary and not guaranteed
57/// to be stable.
58///
59/// [`IdHashMap`]: crate::IdHashMap
60/// [`IdHashMap::iter_mut`]: crate::IdHashMap::iter_mut
61/// [`HashMap`]: std::collections::HashMap
62#[derive(Debug)]
63pub struct IterMut<
64    'a,
65    T: IdHashItem,
66    S = DefaultHashBuilder,
67    A: Allocator = Global,
68> {
69    tables: &'a IdHashMapTables<S, A>,
70    inner: hash_map::ValuesMut<'a, usize, T>,
71}
72
73impl<'a, T: IdHashItem, S: BuildHasher, A: Allocator> IterMut<'a, T, S, A> {
74    pub(super) fn new(
75        tables: &'a IdHashMapTables<S, A>,
76        items: &'a mut ItemSet<T, A>,
77    ) -> Self {
78        Self { tables, inner: items.values_mut() }
79    }
80}
81
82impl<'a, T: IdHashItem, S: Clone + BuildHasher, A: Allocator> Iterator
83    for IterMut<'a, T, S, A>
84{
85    type Item = RefMut<'a, T, S>;
86
87    #[inline]
88    fn next(&mut self) -> Option<Self::Item> {
89        let next = self.inner.next()?;
90        let hashes = self.tables.make_hash(next);
91        Some(RefMut::new(self.tables.state.clone(), hashes, next))
92    }
93}
94
95impl<T: IdHashItem, S: Clone + BuildHasher, A: Allocator> ExactSizeIterator
96    for IterMut<'_, T, S, A>
97{
98    #[inline]
99    fn len(&self) -> usize {
100        self.inner.len()
101    }
102}
103
104// hash_map::IterMut is a FusedIterator, so IterMut is as well.
105impl<T: IdHashItem, S: Clone + BuildHasher, A: Allocator> FusedIterator
106    for IterMut<'_, T, S, A>
107{
108}
109
110/// An iterator over the elements of a [`IdHashMap`] by ownership. Created by
111/// [`IdHashMap::into_iter`].
112///
113/// Similar to [`HashMap`], the iteration order is arbitrary and not guaranteed
114/// to be stable.
115///
116/// [`IdHashMap`]: crate::IdHashMap
117/// [`IdHashMap::into_iter`]: crate::IdHashMap::into_iter
118/// [`HashMap`]: std::collections::HashMap
119#[derive(Debug)]
120pub struct IntoIter<T: IdHashItem, A: Allocator = Global> {
121    inner: hash_map::IntoValues<usize, T, AllocWrapper<A>>,
122}
123
124impl<T: IdHashItem, A: Allocator> IntoIter<T, A> {
125    pub(crate) fn new(items: ItemSet<T, A>) -> Self {
126        Self { inner: items.into_values() }
127    }
128}
129
130impl<T: IdHashItem, A: Allocator> Iterator for IntoIter<T, A> {
131    type Item = T;
132
133    #[inline]
134    fn next(&mut self) -> Option<Self::Item> {
135        self.inner.next()
136    }
137}
138
139impl<T: IdHashItem, A: Allocator> ExactSizeIterator for IntoIter<T, A> {
140    #[inline]
141    fn len(&self) -> usize {
142        self.inner.len()
143    }
144}
145
146// hash_map::IterMut is a FusedIterator, so IterMut is as well.
147impl<T: IdHashItem, A: Allocator> FusedIterator for IntoIter<T, A> {}