linked_hash_table/iter.rs
1//! Iterator types produced by [`LinkedHashMap`].
2//!
3//! All iterator structs are returned by methods on [`LinkedHashMap`]; you
4//! rarely need to name them explicitly.
5//!
6//! | Type | Created by | Yields |
7//! |------|-----------|--------|
8//! | [`Iter`] | [`iter`] | `(&K, &V)` |
9//! | [`IterMut`] | [`iter_mut`] | `(&K, &mut V)` |
10//! | [`Keys`] | [`keys`] | `&K` |
11//! | [`Values`] | [`values`] | `&V` |
12//! | [`ValuesMut`] | [`values_mut`] | `&mut V` |
13//! | [`Drain`] | [`drain`] | `(K, V)`: empties the map |
14//! | [`IntoIter`] | [`into_iter`] | `(K, V)`: consumes the map |
15//!
16//! [`LinkedHashMap`]: crate::LinkedHashMap
17//! [`iter`]: crate::LinkedHashMap::iter
18//! [`iter_mut`]: crate::LinkedHashMap::iter_mut
19//! [`keys`]: crate::LinkedHashMap::keys
20//! [`values`]: crate::LinkedHashMap::values
21//! [`values_mut`]: crate::LinkedHashMap::values_mut
22//! [`drain`]: crate::LinkedHashMap::drain
23//! [`into_iter`]: crate::LinkedHashMap::into_iter
24
25use std::marker::PhantomData;
26use std::ptr::NonNull;
27
28use crate::node::Node;
29
30/// Iterator over `(&K, &V)` pairs in insertion order.
31///
32/// Created by [`LinkedHashMap::iter`](crate::LinkedHashMap::iter).
33pub struct Iter<'a, K, V> {
34 pub(crate) front: *const Node<K, V>,
35 pub(crate) back: *const Node<K, V>,
36 pub(crate) len: usize,
37 // The `PhantomData` ensures that the output references are properly
38 // constrained by the lifetime of the `&LinkedHashMap` that created this iterator.
39 pub(crate) _marker: PhantomData<(&'a K, &'a V)>,
40}
41
42// SAFETY: `Iter` only holds raw traversal pointers plus PhantomData tying
43// yielded references to `'a`. Sending/sharing the iterator is safe when
44// both referenced types are `Sync` (required for `&K`/`&V` across threads).
45unsafe impl<K: Sync, V: Sync> Send for Iter<'_, K, V> {}
46unsafe impl<K: Sync, V: Sync> Sync for Iter<'_, K, V> {}
47
48impl<'a, K, V> Iterator for Iter<'a, K, V> {
49 type Item = (&'a K, &'a V);
50
51 fn next(&mut self) -> Option<Self::Item> {
52 if self.len == 0 {
53 return None;
54 }
55 // SAFETY: `len > 0` guarantees that `front` is a live, fully-initialised
56 // real node (not the tail sentinel). The `PhantomData` lifetime ties the
57 // output references to `'a`, which is the lifetime of the `&LinkedHashMap`.
58 unsafe {
59 let node = self.front;
60 self.front = (*node).next;
61 self.len -= 1;
62 Some((Node::key_ref(node), Node::value_ref(node)))
63 }
64 }
65
66 #[inline]
67 fn size_hint(&self) -> (usize, Option<usize>) {
68 (self.len, Some(self.len))
69 }
70}
71
72impl<'a, K, V> DoubleEndedIterator for Iter<'a, K, V> {
73 fn next_back(&mut self) -> Option<Self::Item> {
74 if self.len == 0 {
75 return None;
76 }
77 // SAFETY: `len > 0` guarantees that `back` is a live real node (not the
78 // head sentinel).
79 unsafe {
80 let node = self.back;
81 self.back = (*node).prev;
82 self.len -= 1;
83 Some((Node::key_ref(node), Node::value_ref(node)))
84 }
85 }
86}
87
88impl<K, V> ExactSizeIterator for Iter<'_, K, V> {}
89
90/// Iterator over `(&K, &mut V)` pairs in insertion order.
91///
92/// Created by [`LinkedHashMap::iter_mut`](crate::LinkedHashMap::iter_mut).
93pub struct IterMut<'a, K, V> {
94 pub(crate) front: *mut Node<K, V>,
95 pub(crate) back: *mut Node<K, V>,
96 pub(crate) len: usize,
97 pub(crate) _marker: PhantomData<(&'a K, &'a mut V)>,
98}
99
100// SAFETY: `IterMut` is created from `&mut LinkedHashMap`, so it has exclusive
101// iteration state. Moving it to another thread is safe when `K: Sync` (for
102// yielded `&K`) and `V: Send` (for yielded `&mut V`).
103unsafe impl<K: Sync, V: Send> Send for IterMut<'_, K, V> {}
104
105impl<'a, K, V> Iterator for IterMut<'a, K, V> {
106 type Item = (&'a K, &'a mut V);
107
108 fn next(&mut self) -> Option<Self::Item> {
109 if self.len == 0 {
110 return None;
111 }
112 // SAFETY: The `&mut LinkedHashMap` borrow that created this iterator
113 // guarantees exclusive access. Each node is yielded exactly once, so
114 // no two outstanding `&mut V` references can alias.
115 unsafe {
116 let node = self.front;
117 self.front = (*node).next;
118 self.len -= 1;
119 Some((Node::key_ref(node), Node::value_mut(node)))
120 }
121 }
122
123 #[inline]
124 fn size_hint(&self) -> (usize, Option<usize>) {
125 (self.len, Some(self.len))
126 }
127}
128
129impl<'a, K, V> DoubleEndedIterator for IterMut<'a, K, V> {
130 fn next_back(&mut self) -> Option<Self::Item> {
131 if self.len == 0 {
132 return None;
133 }
134 // SAFETY: Same as next(), but traversing from the back.
135 unsafe {
136 let node = self.back;
137 self.back = (*node).prev;
138 self.len -= 1;
139 Some((Node::key_ref(node), Node::value_mut(node)))
140 }
141 }
142}
143
144impl<K, V> ExactSizeIterator for IterMut<'_, K, V> {}
145
146/// Iterator over keys in insertion order.
147///
148/// Created by [`LinkedHashMap::keys`](crate::LinkedHashMap::keys).
149pub struct Keys<'a, K, V> {
150 pub(crate) inner: Iter<'a, K, V>,
151}
152
153impl<'a, K, V> Iterator for Keys<'a, K, V> {
154 type Item = &'a K;
155
156 #[inline]
157 fn next(&mut self) -> Option<&'a K> {
158 self.inner.next().map(|(k, _)| k)
159 }
160
161 #[inline]
162 fn size_hint(&self) -> (usize, Option<usize>) {
163 self.inner.size_hint()
164 }
165}
166
167impl<'a, K, V> DoubleEndedIterator for Keys<'a, K, V> {
168 #[inline]
169 fn next_back(&mut self) -> Option<&'a K> {
170 self.inner.next_back().map(|(k, _)| k)
171 }
172}
173
174impl<K, V> ExactSizeIterator for Keys<'_, K, V> {}
175
176/// Iterator over values in insertion order.
177///
178/// Created by [`LinkedHashMap::values`](crate::LinkedHashMap::values).
179pub struct Values<'a, K, V> {
180 pub(crate) inner: Iter<'a, K, V>,
181}
182
183impl<'a, K, V> Iterator for Values<'a, K, V> {
184 type Item = &'a V;
185
186 #[inline]
187 fn next(&mut self) -> Option<&'a V> {
188 self.inner.next().map(|(_, v)| v)
189 }
190
191 #[inline]
192 fn size_hint(&self) -> (usize, Option<usize>) {
193 self.inner.size_hint()
194 }
195}
196
197impl<'a, K, V> DoubleEndedIterator for Values<'a, K, V> {
198 #[inline]
199 fn next_back(&mut self) -> Option<&'a V> {
200 self.inner.next_back().map(|(_, v)| v)
201 }
202}
203
204impl<K, V> ExactSizeIterator for Values<'_, K, V> {}
205
206/// Mutable iterator over values in insertion order.
207///
208/// Created by [`LinkedHashMap::values_mut`](crate::LinkedHashMap::values_mut).
209pub struct ValuesMut<'a, K, V> {
210 pub(crate) inner: IterMut<'a, K, V>,
211}
212
213impl<'a, K, V> Iterator for ValuesMut<'a, K, V> {
214 type Item = &'a mut V;
215
216 #[inline]
217 fn next(&mut self) -> Option<&'a mut V> {
218 self.inner.next().map(|(_, v)| v)
219 }
220
221 #[inline]
222 fn size_hint(&self) -> (usize, Option<usize>) {
223 self.inner.size_hint()
224 }
225}
226
227impl<K, V> ExactSizeIterator for ValuesMut<'_, K, V> {}
228
229/// Draining iterator: removes and yields every `(K, V)` pair in insertion
230/// order, leaving the map empty.
231///
232/// Created by [`LinkedHashMap::drain`](crate::LinkedHashMap::drain).
233/// If the iterator is dropped before it is fully consumed, the remaining
234/// elements are freed and the map's sentinel linkage is restored so the map
235/// can be used again immediately.
236pub struct Drain<'a, K, V> {
237 pub(crate) front: *mut Node<K, V>,
238 pub(crate) tail_ptr: *mut Node<K, V>,
239 pub(crate) head_ptr: *mut Node<K, V>,
240 pub(crate) len: usize,
241 pub(crate) _marker: PhantomData<&'a mut (K, V)>,
242}
243
244// SAFETY: `Drain` has unique ownership of all remaining nodes after
245// `LinkedHashMap::drain` clears the table index. Moving it across threads is
246// safe when moved-out elements are `Send`.
247unsafe impl<K: Send, V: Send> Send for Drain<'_, K, V> {}
248
249impl<K, V> Iterator for Drain<'_, K, V> {
250 type Item = (K, V);
251
252 fn next(&mut self) -> Option<(K, V)> {
253 if self.len == 0 {
254 return None;
255 }
256 // SAFETY: `len > 0` means `front` points to a live real node. We move
257 // the key/value out with `assume_init_read` (the MaybeUninit slots are
258 // now logically uninitialised) and then free the bare Node allocation.
259 unsafe {
260 let node = self.front;
261 self.front = (*node).next;
262 self.len -= 1;
263 let k = Node::key_read(node);
264 let v = Node::value_read(node);
265 let _ = Box::from_raw(node); // free allocation; fields already moved
266 Some((k, v))
267 }
268 }
269
270 #[inline]
271 fn size_hint(&self) -> (usize, Option<usize>) {
272 (self.len, Some(self.len))
273 }
274}
275
276impl<K, V> Drop for Drain<'_, K, V> {
277 fn drop(&mut self) {
278 // Eagerly drop any nodes that the caller did not consume.
279 // SAFETY: Remaining nodes are live and fully initialised. The owning
280 // map's HashMap index was cleared before Drain was created, so these
281 // nodes are exclusively owned by this iterator.
282 unsafe {
283 let mut cur = self.front;
284 while cur != self.tail_ptr {
285 let next = (*cur).next;
286 Node::drop_real(cur);
287 cur = next;
288 }
289 // Restore the sentinel linkage so the map is in a valid empty state
290 // the moment Drain is dropped.
291 (*self.head_ptr).next = self.tail_ptr;
292 (*self.tail_ptr).prev = self.head_ptr;
293 }
294 }
295}
296
297impl<K, V> ExactSizeIterator for Drain<'_, K, V> {}
298
299/// Consuming iterator: yields every `(K, V)` pair in insertion order,
300/// consuming the map.
301///
302/// Created by calling `.into_iter()` on a [`LinkedHashMap`](crate::LinkedHashMap).
303pub struct IntoIter<K, V> {
304 pub(crate) front: *mut Node<K, V>,
305 pub(crate) tail: NonNull<Node<K, V>>,
306 pub(crate) head: NonNull<Node<K, V>>,
307 pub(crate) len: usize,
308}
309
310// SAFETY: IntoIter exclusively owns all the nodes it points to (it takes
311// ownership from the map via mem::forget + ptr::read). No aliasing is
312// possible.
313unsafe impl<K: Send, V: Send> Send for IntoIter<K, V> {}
314unsafe impl<K: Sync, V: Sync> Sync for IntoIter<K, V> {}
315
316impl<K, V> Iterator for IntoIter<K, V> {
317 type Item = (K, V);
318
319 fn next(&mut self) -> Option<(K, V)> {
320 if self.len == 0 {
321 return None;
322 }
323 // SAFETY: `len > 0` guarantees `front` is a live real node.
324 unsafe {
325 let node = self.front;
326 self.front = (*node).next;
327 self.len -= 1;
328 let k = Node::key_read(node);
329 let v = Node::value_read(node);
330 let _ = Box::from_raw(node);
331 Some((k, v))
332 }
333 }
334
335 #[inline]
336 fn size_hint(&self) -> (usize, Option<usize>) {
337 (self.len, Some(self.len))
338 }
339}
340
341impl<K, V> Drop for IntoIter<K, V> {
342 fn drop(&mut self) {
343 // Free un-consumed real nodes.
344 // SAFETY: Remaining nodes are live, real, and exclusively owned by
345 // this iterator.
346 unsafe {
347 let mut cur = self.front;
348 while cur != self.tail.as_ptr() {
349 let next = (*cur).next;
350 Node::drop_real(cur);
351 cur = next;
352 }
353 // Free the two sentinel nodes whose key/value are uninitialised.
354 Node::drop_sentinel(self.head.as_ptr());
355 Node::drop_sentinel(self.tail.as_ptr());
356 }
357 }
358}
359
360impl<K, V> ExactSizeIterator for IntoIter<K, V> {}
361
362// Variance assertions
363//
364// These compile-time checks verify that each iterator type is *covariant*
365// in its lifetime and type parameters: a longer lifetime / more-derived type
366// can be shortened / widened to match a shorter lifetime / less-derived type.
367//
368// The pattern is: write a function that accepts the "longer" type and returns
369// the "shorter" type with only implicit subtyping — if the compiler accepts it,
370// the type is covariant in those parameters.
371
372#[cfg(not(coverage))]
373const _: () = {
374 /// `Iter<'long, K, V>` is covariant in `'a`, `K`, and `V`.
375 fn _check_iter<'long: 'short, 'short, K, V>(x: Iter<'long, K, V>) -> Iter<'short, K, V> {
376 x
377 }
378
379 /// `IterMut<'long, K, V>` is covariant in `'a` and `K`, but NOT in `V`
380 /// (it yields `&'a mut V`). We only assert covariance in `'a` and `K`.
381 fn _check_iter_mut_lifetime<'long: 'short, 'short, K, V>(
382 x: IterMut<'long, K, V>,
383 ) -> IterMut<'short, K, V> {
384 x
385 }
386
387 /// `Keys<'long, K, V>` is covariant in `'a` and `K`.
388 fn _check_keys<'long: 'short, 'short, K, V>(x: Keys<'long, K, V>) -> Keys<'short, K, V> {
389 x
390 }
391
392 /// `Values<'long, K, V>` is covariant in `'a` and `V`.
393 fn _check_values<'long: 'short, 'short, K, V>(x: Values<'long, K, V>) -> Values<'short, K, V> {
394 x
395 }
396
397 /// `IntoIter<K, V>` is covariant in `K` and `V`.
398 ///
399 /// Since `IntoIter` has no lifetime, we verify this by confirming that the
400 /// struct compiles and the PhantomData annotation is sound. The owned
401 /// `(K, V)` pairs it yields make covariance safe.
402 fn _check_into_iter<K, V>(_: IntoIter<K, V>) {}
403};