Skip to main content

leapfrog/
hashiter.rs

1use crate::{hashmap::HashMap, Value};
2
3use core::hash::{BuildHasher, Hash};
4
5#[cfg(feature = "stable_alloc")]
6use allocator_api2::alloc::Allocator;
7#[cfg(not(feature = "stable_alloc"))]
8use std::alloc::Allocator;
9
10/// Iterator over a [`HashMap`] which yields key-value pairs.
11///
12/// # Examples
13///
14/// ```
15/// use leapfrog::HashMap;
16///
17/// let mut map = HashMap::new();
18///
19/// map.insert(12u32, 17u64);
20/// map.insert(42u32, 92u64);
21///
22/// let pairs = map.into_iter().collect::<Vec<(u32, u64)>>();
23/// assert_eq!(pairs.len(), 2);
24/// ```
25pub struct OwnedIter<K, V, H: BuildHasher, A: Allocator> {
26    map: HashMap<K, V, H, A>,
27    current: usize,
28}
29
30impl<K, V, H, A> OwnedIter<K, V, H, A>
31where
32    K: Eq + Hash + Clone,
33    V: Value,
34    H: BuildHasher,
35    A: Allocator,
36{
37    pub(crate) fn new(map: HashMap<K, V, H, A>) -> Self {
38        Self {
39            map,
40            current: 0usize,
41        }
42    }
43}
44
45impl<K, V, H, A> Iterator for OwnedIter<K, V, H, A>
46where
47    K: Eq + Hash + Clone,
48    V: Value,
49    H: BuildHasher + Default,
50    A: Allocator,
51{
52    type Item = (K, V);
53
54    fn next(&mut self) -> Option<Self::Item> {
55        loop {
56            let current = self.current;
57            if let Some(cell) = self.map.get_cell_at_index(current) {
58                self.current = current + 1;
59                if cell.is_empty() || cell.value.is_null() {
60                    continue;
61                }
62
63                return Some((cell.key.clone(), cell.value));
64            } else {
65                return None;
66            }
67        }
68    }
69}
70
71unsafe impl<K, V, H, A> Send for OwnedIter<K, V, H, A>
72where
73    K: Send,
74    V: Send,
75    H: BuildHasher + Send,
76    A: Allocator + Send,
77{
78}
79
80unsafe impl<K, V, H, A> Sync for OwnedIter<K, V, H, A>
81where
82    K: Sync,
83    V: Sync,
84    H: BuildHasher + Sync,
85    A: Allocator + Sync,
86{
87}
88
89/// Iterator over a [`HashMap`] which yields immutable key-value reference pairs.
90///
91/// # Examples
92///
93/// ```
94/// use leapfrog::HashMap;
95///
96/// let mut map = HashMap::new();
97///
98/// map.insert(12, 17);
99/// map.insert(42, 23);
100///
101/// assert_eq!(map.iter().count(), 2);
102/// ```
103pub struct Iter<'a, K, V, H: BuildHasher, A: Allocator> {
104    map: &'a HashMap<K, V, H, A>,
105    current: usize,
106}
107
108impl<'a, K, V, H, A> Clone for Iter<'a, K, V, H, A>
109where
110    K: Eq + Hash + Clone,
111    V: Value,
112    H: BuildHasher + Default,
113    A: Allocator,
114{
115    fn clone(&self) -> Self {
116        Iter::new(self.map)
117    }
118}
119
120impl<'a, K, V, H, A> Iter<'a, K, V, H, A>
121where
122    K: Eq + Hash + Clone,
123    V: Value,
124    H: BuildHasher + 'a,
125    A: Allocator + 'a,
126{
127    pub(crate) fn new(map: &'a HashMap<K, V, H, A>) -> Self {
128        Self {
129            map,
130            current: 0usize,
131        }
132    }
133}
134
135impl<'a, K, V, H, A> Iterator for Iter<'a, K, V, H, A>
136where
137    K: Eq + Hash + Clone,
138    V: Value,
139    H: BuildHasher + Default + 'a,
140    A: Allocator + 'a,
141{
142    type Item = (&'a K, &'a V);
143
144    fn next(&mut self) -> Option<Self::Item> {
145        loop {
146            let current = self.current;
147            if let Some(cell) = self.map.get_cell_at_index(current) {
148                self.current = current + 1;
149                if cell.is_empty() || cell.value.is_null() {
150                    continue;
151                }
152
153                return Some((&cell.key, &cell.value));
154            } else {
155                return None;
156            }
157        }
158    }
159}
160
161unsafe impl<'a, K, V, H, A> Send for Iter<'a, K, V, H, A>
162where
163    K: Send,
164    V: Send,
165    H: BuildHasher + Send + 'a,
166    A: Allocator + Send + 'a,
167{
168}
169
170unsafe impl<'a, K, V, H, A> Sync for Iter<'a, K, V, H, A>
171where
172    K: Sync,
173    V: Sync,
174    H: BuildHasher + Sync + 'a,
175    A: Allocator + Sync + 'a,
176{
177}
178
179/// Iterator over a [`HashMap`] which yields mutable key-value reference pairs.
180///
181/// # Examples
182///
183/// ```
184/// use leapfrog::HashMap;
185///
186/// let mut map = HashMap::new();
187///
188/// map.insert(12, 17);
189/// map.insert(42, 23);
190///
191/// assert_eq!(map.iter_mut().count(), 2);
192/// ```
193pub struct IterMut<'a, K, V, H: BuildHasher, A: Allocator> {
194    map: &'a mut HashMap<K, V, H, A>,
195    current: usize,
196}
197
198impl<'a, K, V, H, A> IterMut<'a, K, V, H, A>
199where
200    K: Eq + Hash + Clone,
201    V: Value,
202    H: BuildHasher + 'a,
203    A: Allocator + 'a,
204{
205    pub(crate) fn new(map: &'a mut HashMap<K, V, H, A>) -> Self {
206        Self {
207            map,
208            current: 0usize,
209        }
210    }
211}
212
213impl<'a, K, V, H, A> Iterator for IterMut<'a, K, V, H, A>
214where
215    K: Eq + Hash + Clone,
216    V: Value,
217    H: BuildHasher + Default + 'a,
218    A: Allocator + 'a,
219{
220    type Item = (&'a K, &'a mut V);
221
222    fn next(&mut self) -> Option<Self::Item> {
223        loop {
224            let current = self.current;
225            if let Some(cell) = self.map.get_cell_at_index_mut(current) {
226                self.current = current + 1;
227                if cell.is_empty() || cell.value.is_null() {
228                    continue;
229                }
230
231                return Some((&cell.key, &mut cell.value));
232            } else {
233                return None;
234            }
235        }
236    }
237}
238
239unsafe impl<'a, K, V, H, A> Send for IterMut<'a, K, V, H, A>
240where
241    K: Send,
242    V: Send,
243    H: BuildHasher + Send + 'a,
244    A: Allocator + Send + 'a,
245{
246}
247
248unsafe impl<'a, K, V, H, A> Sync for IterMut<'a, K, V, H, A>
249where
250    K: Sync,
251    V: Sync,
252    H: BuildHasher + Sync + 'a,
253    A: Allocator + Sync + 'a,
254{
255}