Skip to main content

iddqd/id_hash_map/
iter.rs

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