const_lru/iters/
iter.rs

1use num_traits::{PrimInt, Unsigned};
2
3use crate::ConstLru;
4
5use super::double_ended_iter_cursors::DoubleEndedIterCursors;
6
7/// Iterates through the keys and values of the `ConstLru` from most-recently-used to least-recently-used
8///
9/// Does not change the LRU order of the elements.
10pub struct Iter<'a, K, V, const CAP: usize, I: PrimInt + Unsigned> {
11    cursors: DoubleEndedIterCursors<I, CAP>,
12    const_lru: &'a ConstLru<K, V, CAP, I>,
13}
14
15impl<'a, K, V, const CAP: usize, I: PrimInt + Unsigned> Iter<'a, K, V, CAP, I> {
16    pub fn new(const_lru: &'a ConstLru<K, V, CAP, I>) -> Self {
17        let cursors = DoubleEndedIterCursors::new(const_lru);
18        Self { cursors, const_lru }
19    }
20
21    fn get_entry(&mut self, i: usize) -> (&'a K, &'a V) {
22        let key = unsafe { self.const_lru.keys[i].assume_init_ref() };
23        let val = unsafe { self.const_lru.values[i].assume_init_ref() };
24        (key, val)
25    }
26}
27
28impl<'a, K, V, const CAP: usize, I: PrimInt + Unsigned> Iterator for Iter<'a, K, V, CAP, I> {
29    type Item = (&'a K, &'a V);
30
31    fn next(&mut self) -> Option<Self::Item> {
32        if self.cursors.has_ended() {
33            return None;
34        }
35        // consume then increment
36        let i = self.cursors.get_from_head_idx();
37        self.cursors.advance_from_head(self.const_lru);
38        Some(self.get_entry(i))
39    }
40
41    // TODO: look into https://doc.rust-lang.org/std/iter/trait.TrustedLen.html
42    // and consider adding a `seen` field to implement it
43    // when it lands in stable
44    fn size_hint(&self) -> (usize, Option<usize>) {
45        (0, Some(CAP))
46    }
47}
48
49impl<'a, K, V, const CAP: usize, I: PrimInt + Unsigned> DoubleEndedIterator
50    for Iter<'a, K, V, CAP, I>
51{
52    fn next_back(&mut self) -> Option<Self::Item> {
53        if self.cursors.has_ended() {
54            return None;
55        }
56        // decrement then consume
57        self.cursors.retreat_from_tail(self.const_lru);
58        let i = self.cursors.get_from_tail_idx();
59        Some(self.get_entry(i))
60    }
61}