standard_lib/collections/hash/map/
iter.rs

1use std::hash::{BuildHasher, Hash};
2use std::iter::FusedIterator;
3use std::slice::Iter as ArrIter;
4use std::slice::IterMut as ArrIterMut;
5
6use super::{Bucket, HashMap};
7use crate::collections::contiguous::array::IntoIter as ArrIntoIter;
8
9impl<K: Hash + Eq, V, B: BuildHasher> IntoIterator for HashMap<K, V, B> {
10    type Item = (K, V);
11
12    type IntoIter = IntoIter<K, V>;
13
14    fn into_iter(self) -> Self::IntoIter {
15        IntoIter {
16            len: self.len(),
17            inner: self.arr.into_iter(),
18        }
19    }
20}
21
22/// A type for owned iteration over a [`HashMap`]. Produces values of type `(K, V)`.
23///
24/// See [`HashMap::into_iter`].
25pub struct IntoIter<K, V> {
26    pub(crate) inner: ArrIntoIter<Bucket<K, V>>,
27    pub(crate) len: usize,
28}
29
30impl<K: Hash + Eq, V> Iterator for IntoIter<K, V> {
31    type Item = (K, V);
32
33    fn next(&mut self) -> Option<Self::Item> {
34        let mut next = self.inner.next();
35        while let Some(None) = next {
36            next = self.inner.next();
37        }
38
39        next.flatten()
40    }
41
42    fn size_hint(&self) -> (usize, Option<usize>) {
43        (0, Some(self.len))
44    }
45}
46
47impl<K: Hash + Eq, V> FusedIterator for IntoIter<K, V> {}
48
49impl<'a, K: Hash + Eq, V, B: BuildHasher> IntoIterator for &'a HashMap<K, V, B> {
50    type Item = (&'a K, &'a V);
51
52    type IntoIter = Iter<'a, K, V>;
53
54    fn into_iter(self) -> Self::IntoIter {
55        Iter {
56            len: self.len(),
57            inner: self.arr.iter(),
58        }
59    }
60}
61
62/// A type for borrowed iteration over a [`HashMap`]. Produces values of type `(&K, &V)`.
63///
64/// See [`HashMap::iter`].
65pub struct Iter<'a, K, V> {
66    pub(crate) inner: ArrIter<'a, Bucket<K, V>>,
67    pub(crate) len: usize,
68}
69
70impl<'a, K: Hash + Eq, V> Iterator for Iter<'a, K, V> {
71    type Item = (&'a K, &'a V);
72
73    fn next(&mut self) -> Option<Self::Item> {
74        let mut next = self.inner.next();
75        while let Some(None) = next {
76            next = self.inner.next();
77        }
78
79        // Convert &'a (K, V) to (&'a K, &'a V) to avoid promising the internal use of a tuple.
80        next.and_then(|i| i.as_ref().map(|(k, v)| (k, v)))
81    }
82
83    fn size_hint(&self) -> (usize, Option<usize>) {
84        (0, Some(self.len))
85    }
86}
87
88impl<'a, K: Hash + Eq, V> FusedIterator for Iter<'a, K, V> {}
89
90/// A type for owned iteration over a [`HashMap`]'s keys. Produces values of type `K`.
91///
92/// See [`HashMap::into_keys`].
93pub struct IntoKeys<K, V>(pub(crate) IntoIter<K, V>);
94
95impl<K: Hash + Eq, V> Iterator for IntoKeys<K, V> {
96    type Item = K;
97
98    fn next(&mut self) -> Option<Self::Item> {
99        self.0.next().map(|(k, _)| k)
100    }
101
102    fn size_hint(&self) -> (usize, Option<usize>) {
103        self.0.size_hint()
104    }
105}
106
107impl<K: Hash + Eq, V> FusedIterator for IntoKeys<K, V> {}
108
109/// A type for borrowed iteration over a [`HashMap`]'s keys. Produces values of type `&K`.
110///
111/// See [`HashMap::keys`].
112pub struct Keys<'a, K, V>(pub(crate) Iter<'a, K, V>);
113
114impl<'a, K: Hash + Eq, V> Iterator for Keys<'a, K, V> {
115    type Item = &'a K;
116
117    fn next(&mut self) -> Option<Self::Item> {
118        self.0.next().map(|(k, _)| k)
119    }
120
121    fn size_hint(&self) -> (usize, Option<usize>) {
122        self.0.size_hint()
123    }
124}
125
126impl<'a, K: Hash + Eq, V> FusedIterator for Keys<'a, K, V> {}
127
128/// A type for owned iteration over a [`HashMap`]'s values. Produces values of type `V`.
129///
130/// See [`HashMap::into_values`].
131pub struct IntoValues<K, V>(pub(crate) IntoIter<K, V>);
132
133impl<K: Hash + Eq, V> Iterator for IntoValues<K, V> {
134    type Item = V;
135
136    fn next(&mut self) -> Option<Self::Item> {
137        self.0.next().map(|(_, v)| v)
138    }
139
140    fn size_hint(&self) -> (usize, Option<usize>) {
141        self.0.size_hint()
142    }
143}
144
145impl<K: Hash + Eq, V> FusedIterator for IntoValues<K, V> {}
146
147/// A type for mutable iteration over a [`HashMap`]'s values. Produces values of type `&mut V`.
148///
149/// See [`HashMap::values_mut`].
150pub struct ValuesMut<'a, K, V> {
151    pub(crate) inner: ArrIterMut<'a, Bucket<K, V>>,
152    pub(crate) len: usize,
153}
154
155impl<'a, K: Hash + Eq, V> Iterator for ValuesMut<'a, K, V> {
156    type Item = &'a mut V;
157
158    fn next(&mut self) -> Option<Self::Item> {
159        let mut next = self.inner.next();
160        while let Some(None) = next {
161            next = self.inner.next();
162        }
163
164        next.and_then(|i| i.as_mut().map(|(_, v)| v))
165    }
166
167    fn size_hint(&self) -> (usize, Option<usize>) {
168        (0, Some(self.len))
169    }
170}
171
172impl<'a, K: Hash + Eq, V> FusedIterator for ValuesMut<'a, K, V> {}
173
174/// A type for borrowed iteration over a [`HashMap`]'s values. Produces values of type `&V`.
175///
176/// See [`HashMap::values`].
177pub struct Values<'a, K, V>(pub(crate) Iter<'a, K, V>);
178
179impl<'a, K: Hash + Eq, V> Iterator for Values<'a, K, V> {
180    type Item = &'a V;
181
182    fn next(&mut self) -> Option<Self::Item> {
183        self.0.next().map(|(_, v)| v)
184    }
185
186    fn size_hint(&self) -> (usize, Option<usize>) {
187        self.0.size_hint()
188    }
189}
190
191impl<'a, K: Hash + Eq, V> FusedIterator for Values<'a, K, V> {}