loro_thunderdome/iter/
iter.rs

1use core::iter::{ExactSizeIterator, FusedIterator};
2use core::slice;
3
4use crate::arena::{Entry, Index};
5
6/// See [`Arena::iter`](crate::Arena::iter).
7pub struct Iter<'a, T> {
8    pub(crate) len: u32,
9    pub(crate) slot: u32,
10    pub(crate) inner: slice::Iter<'a, Entry<T>>,
11}
12
13impl<'a, T> Iterator for Iter<'a, T> {
14    type Item = (Index, &'a T);
15
16    fn next(&mut self) -> Option<Self::Item> {
17        loop {
18            if self.len == 0 {
19                return None;
20            }
21
22            let slot = self.slot;
23            self.slot = self
24                .slot
25                .checked_add(1)
26                .unwrap_or_else(|| unreachable!("Overflowed u32 trying to iterate Arena"));
27
28            match self.inner.next()? {
29                Entry::Empty(_) => (),
30                Entry::Occupied(occupied) => {
31                    self.len = self
32                        .len
33                        .checked_sub(1)
34                        .unwrap_or_else(|| unreachable!("Underflowed u32 trying to iterate Arena"));
35
36                    let index = Index {
37                        slot,
38                        generation: occupied.generation,
39                    };
40
41                    return Some((index, &occupied.value));
42                }
43            }
44        }
45    }
46
47    fn size_hint(&self) -> (usize, Option<usize>) {
48        (self.len as usize, Some(self.len as usize))
49    }
50}
51
52impl<'a, T> FusedIterator for Iter<'a, T> {}
53impl<'a, T> ExactSizeIterator for Iter<'a, T> {}
54
55#[cfg(all(test, feature = "std"))]
56mod test {
57    use crate::Arena;
58
59    use std::collections::HashSet;
60
61    #[test]
62    fn iter() {
63        let mut arena = Arena::with_capacity(2);
64        let one = arena.insert(1);
65        let two = arena.insert(2);
66
67        let mut pairs = HashSet::new();
68        let mut iter = arena.iter();
69        assert_eq!(iter.size_hint(), (2, Some(2)));
70
71        pairs.insert(iter.next().unwrap());
72        assert_eq!(iter.size_hint(), (1, Some(1)));
73
74        pairs.insert(iter.next().unwrap());
75        assert_eq!(iter.size_hint(), (0, Some(0)));
76
77        assert_eq!(iter.next(), None);
78        assert_eq!(iter.next(), None);
79        assert_eq!(iter.size_hint(), (0, Some(0)));
80
81        assert!(pairs.contains(&(one, &1)));
82        assert!(pairs.contains(&(two, &2)));
83    }
84}