option_block/iter.rs
1//! By-value and by-reference iterator objects for the various block variants.
2//! Note that these types cannot be used directly. They are simply part of the
3//! public interface just in case one needs to explicitly "name" the iterator
4//! object in their code.
5//!
6//! # Example
7//!
8//! ```rust
9//! let block: option_block::Block8<_> = [10, 8, 1].into_iter().enumerate().collect();
10//! assert_eq!(block.get(0), Some(&10));
11//! assert_eq!(block.get(1), Some(&8));
12//! assert_eq!(block.get(2), Some(&1));
13//! assert!(block.get(3).is_none());
14//! ```
15
16use core::ops::Range;
17
18macro_rules! impl_iterator_outer {
19 ($name:ident $into_iter:ident $iter:ident) => {
20 /// By-value iterator that consumes the block allocation.
21 pub struct $into_iter<T> {
22 pub(crate) block: $crate::$name<T>,
23 pub(crate) index: Range<usize>,
24 }
25
26 impl<T> Iterator for $into_iter<T> {
27 type Item = T;
28 fn next(&mut self) -> Option<Self::Item> {
29 Some(loop {
30 let idx = self.index.next()?;
31 if let Some(val) = self.block.remove(idx) {
32 break val;
33 }
34 })
35 }
36 }
37
38 /// By-reference iterator that borrows from the block allocation.
39 pub struct $iter<'a, T> {
40 pub(crate) block: &'a $crate::$name<T>,
41 pub(crate) index: Range<usize>,
42 }
43
44 impl<'a, T> Iterator for $iter<'a, T> {
45 type Item = &'a T;
46 fn next(&mut self) -> Option<Self::Item> {
47 Some(loop {
48 let idx = self.index.next()?;
49 if let Some(val) = self.block.get(idx) {
50 break val;
51 }
52 })
53 }
54 }
55 };
56}
57
58impl_iterator_outer!(Block8 Block8IntoIter Block8Iter);
59impl_iterator_outer!(Block16 Block16IntoIter Block16Iter);
60impl_iterator_outer!(Block32 Block32IntoIter Block32Iter);
61impl_iterator_outer!(Block64 Block64IntoIter Block64Iter);
62impl_iterator_outer!(Block128 Block128IntoIter Block128Iter);