1 | use std::{iter::FusedIterator, slice}; |
2 | |
3 | use crate::{cfg, page, shard}; |
4 | |
5 | /// An exclusive fused iterator over the items in a [`Slab`](crate::Slab). |
6 | #[must_use = "iterators are lazy and do nothing unless consumed" ] |
7 | #[derive(Debug)] |
8 | pub struct UniqueIter<'a, T, C: cfg::Config> { |
9 | pub(super) shards: shard::IterMut<'a, Option<T>, C>, |
10 | pub(super) pages: slice::Iter<'a, page::Shared<Option<T>, C>>, |
11 | pub(super) slots: Option<page::Iter<'a, T, C>>, |
12 | } |
13 | |
14 | impl<'a, T, C: cfg::Config> Iterator for UniqueIter<'a, T, C> { |
15 | type Item = &'a T; |
16 | |
17 | fn next(&mut self) -> Option<Self::Item> { |
18 | test_println!("UniqueIter::next" ); |
19 | loop { |
20 | test_println!("-> try next slot" ); |
21 | if let Some(item) = self.slots.as_mut().and_then(|slots| slots.next()) { |
22 | test_println!("-> found an item!" ); |
23 | return Some(item); |
24 | } |
25 | |
26 | test_println!("-> try next page" ); |
27 | if let Some(page) = self.pages.next() { |
28 | test_println!("-> found another page" ); |
29 | self.slots = page.iter(); |
30 | continue; |
31 | } |
32 | |
33 | test_println!("-> try next shard" ); |
34 | if let Some(shard) = self.shards.next() { |
35 | test_println!("-> found another shard" ); |
36 | self.pages = shard.iter(); |
37 | } else { |
38 | test_println!("-> all done!" ); |
39 | return None; |
40 | } |
41 | } |
42 | } |
43 | } |
44 | |
45 | impl<T, C: cfg::Config> FusedIterator for UniqueIter<'_, T, C> {} |
46 | |