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);