micromap_rawl/
iterators.rs

1use crate::{IntoIter, Iter, IterMut, Map};
2use core::iter::FusedIterator;
3
4impl<K: PartialEq, V, const N: usize> Map<K, V, N> {
5    /// Make an iterator over all pairs.
6    #[inline]
7    #[must_use]
8    pub fn iter(&self) -> Iter<K, V> {
9        self.into_iter()
10    }
11
12    /// An iterator with mutable references to the values but
13    #[inline]
14    pub fn iter_mut(&mut self) -> IterMut<K, V> {
15        self.into_iter()
16    }
17}
18
19impl<'a, K, V> Iterator for Iter<'a, K, V> {
20    type Item = (&'a K, &'a V);
21
22    #[inline]
23    #[must_use]
24    fn next(&mut self) -> Option<Self::Item> {
25        self.iter.next().map(|p| {
26            let p = unsafe { p.assume_init_ref() };
27            (&p.0, &p.1)
28        })
29    }
30
31    #[inline]
32    fn size_hint(&self) -> (usize, Option<usize>) {
33        self.iter.size_hint()
34    }
35}
36
37impl<'a, K, V> Iterator for IterMut<'a, K, V> {
38    type Item = (&'a K, &'a mut V);
39
40    #[inline]
41    fn next(&mut self) -> Option<Self::Item> {
42        self.iter.next().map(|p| {
43            let p = unsafe { p.assume_init_mut() };
44            (&p.0, &mut p.1)
45        })
46    }
47
48    #[inline]
49    fn size_hint(&self) -> (usize, Option<usize>) {
50        self.iter.size_hint()
51    }
52}
53
54impl<K: PartialEq, V, const N: usize> Iterator for IntoIter<K, V, N> {
55    type Item = (K, V);
56
57    #[inline]
58    #[must_use]
59    fn next(&mut self) -> Option<Self::Item> {
60        if self.map.len > 0 {
61            self.map.len -= 1;
62            Some(self.map.item_read(self.map.len))
63        } else {
64            None
65        }
66    }
67
68    #[inline]
69    fn size_hint(&self) -> (usize, Option<usize>) {
70        (self.map.len, Some(self.map.len))
71    }
72}
73
74impl<'a, K: PartialEq, V, const N: usize> IntoIterator for &'a Map<K, V, N> {
75    type Item = (&'a K, &'a V);
76    type IntoIter = Iter<'a, K, V>;
77
78    #[inline]
79    #[must_use]
80    fn into_iter(self) -> Self::IntoIter {
81        Iter {
82            iter: self.pairs[0..self.len].iter(),
83        }
84    }
85}
86
87impl<'a, K: PartialEq, V, const N: usize> IntoIterator for &'a mut Map<K, V, N> {
88    type Item = (&'a K, &'a mut V);
89    type IntoIter = IterMut<'a, K, V>;
90
91    #[inline]
92    fn into_iter(self) -> Self::IntoIter {
93        IterMut {
94            iter: self.pairs[0..self.len].iter_mut(),
95        }
96    }
97}
98
99impl<K: PartialEq, V, const N: usize> IntoIterator for Map<K, V, N> {
100    type Item = (K, V);
101    type IntoIter = IntoIter<K, V, N>;
102
103    #[inline]
104    #[must_use]
105    fn into_iter(self) -> Self::IntoIter {
106        IntoIter { map: self }
107    }
108}
109
110impl<K, V> ExactSizeIterator for Iter<'_, K, V> {
111    fn len(&self) -> usize {
112        self.iter.len()
113    }
114}
115
116impl<K, V> ExactSizeIterator for IterMut<'_, K, V> {
117    fn len(&self) -> usize {
118        self.iter.len()
119    }
120}
121
122impl<K: PartialEq, V, const N: usize> ExactSizeIterator for IntoIter<K, V, N> {
123    fn len(&self) -> usize {
124        self.map.len
125    }
126}
127
128impl<K, V> FusedIterator for Iter<'_, K, V> {}
129
130impl<K, V> FusedIterator for IterMut<'_, K, V> {}
131
132impl<K: PartialEq, V, const N: usize> FusedIterator for IntoIter<K, V, N> {}
133
134#[cfg(test)]
135mod test {
136    use super::*;
137
138    #[test]
139    fn empty_iterator() {
140        let m: Map<u32, u32, 4> = Map::new();
141        assert!(m.into_iter().next().is_none());
142    }
143
144    #[test]
145    fn insert_and_jump_over_next() {
146        let mut m: Map<String, i32, 10> = Map::new();
147        m.insert("foo".to_string(), 42);
148        let mut iter = m.into_iter();
149        assert_eq!(42, iter.next().unwrap().1);
150        assert!(iter.next().is_none());
151    }
152
153    #[test]
154    fn insert_and_iterate() {
155        let mut m: Map<String, i32, 10> = Map::new();
156        m.insert("one".to_string(), 42);
157        m.insert("two".to_string(), 16);
158        let mut sum = 0;
159        for (_k, v) in m.iter() {
160            sum += v;
161        }
162        assert_eq!(58, sum);
163    }
164
165    #[test]
166    fn insert_and_into_iterate() {
167        let mut m: Map<String, i32, 10> = Map::new();
168        m.insert("one".to_string(), 42);
169        m.insert("two".to_string(), 16);
170        let mut sum = 0;
171        for p in &m {
172            sum += p.1;
173        }
174        assert_eq!(58, sum);
175    }
176
177    #[test]
178    fn iterate_with_blanks() {
179        let mut m: Map<String, i32, 10> = Map::new();
180        m.insert("one".to_string(), 1);
181        m.insert("two".to_string(), 3);
182        m.insert("three".to_string(), 5);
183        m.remove("two");
184        let mut sum = 0;
185        for (_k, v) in m.iter() {
186            sum += v;
187        }
188        assert_eq!(6, sum);
189    }
190
191    #[test]
192    fn into_iterate_with_blanks() {
193        let mut m: Map<String, i32, 10> = Map::new();
194        m.insert("one".to_string(), 1);
195        m.insert("two".to_string(), 3);
196        m.insert("three".to_string(), 5);
197        m.remove("two");
198        let mut sum = 0;
199        for (_k, v) in m {
200            sum += v;
201        }
202        assert_eq!(6, sum);
203    }
204
205    #[test]
206    fn change_with_iter_mut() {
207        let mut m: Map<String, i32, 10> = Map::new();
208        m.insert("one".to_string(), 2);
209        m.insert("two".to_string(), 3);
210        m.insert("three".to_string(), 5);
211        for (_k, v) in m.iter_mut() {
212            *v *= 2;
213        }
214        let sum = m.iter().map(|p| p.1).sum::<i32>();
215        assert_eq!(20, sum);
216    }
217
218    #[test]
219    fn iter_mut_with_blanks() {
220        let mut m: Map<String, i32, 10> = Map::new();
221        m.insert("one".to_string(), 1);
222        m.insert("two".to_string(), 3);
223        m.insert("three".to_string(), 5);
224        assert_eq!(m.iter_mut().count(), 3);
225        m.remove("two");
226        assert_eq!(m.iter_mut().count(), 2);
227        assert_eq!(m.iter_mut().last().unwrap().1, &5);
228    }
229
230    #[test]
231    fn into_iter_mut() {
232        let mut m: Map<String, i32, 10> = Map::new();
233        m.insert("one".to_string(), 2);
234        m.insert("two".to_string(), 3);
235        m.insert("three".to_string(), 5);
236        for (_k, v) in &mut m {
237            *v *= 2;
238        }
239        let sum = m.iter().map(|p| p.1).sum::<i32>();
240        assert_eq!(20, sum);
241    }
242
243    #[test]
244    fn into_iter_drop() {
245        use std::rc::Rc;
246        let mut m: Map<i32, Rc<()>, 8> = Map::new();
247        let v = Rc::new(());
248        let n = 8;
249        for i in 0..n {
250            m.insert(i, Rc::clone(&v));
251        }
252        assert_eq!(Rc::strong_count(&v), (n + 1) as usize);
253        let _p = m.into_iter().nth(3);
254        assert_eq!(Rc::strong_count(&v), 2); // v & p
255    }
256}