1#[derive(Clone)]
12pub struct NormalizedRangeCheckingIterator<I> {
13 iter: I,
14 prev: Option<crate::Range>,
15}
16
17impl<I> NormalizedRangeCheckingIterator<I>
18where
19 I: Iterator<Item = crate::Range>,
20{
21 pub fn new(ranges: impl IntoIterator<IntoIter = I>) -> Self {
22 Self { iter: ranges.into_iter(), prev: None }
23 }
24}
25
26impl<I> Iterator for NormalizedRangeCheckingIterator<I>
27where
28 I: Iterator<Item = crate::Range>,
29{
30 type Item = crate::Range;
31
32 fn next(&mut self) -> Option<crate::Range> {
33 let cur = self.iter.next()?;
34 if let Some(prev) = self.prev {
35 assert!(prev.end() < cur.addr() || (prev.end() == cur.addr() && prev.ty() != cur.ty()));
36 }
37 self.prev = Some(cur);
38 Some(cur)
39 }
40}
41
42unsafe impl<I> crate::NormalizedRangeIterator for NormalizedRangeCheckingIterator<I> where
44 I: Iterator<Item = crate::Range>
45{
46}
47
48#[cfg(test)]
49mod tests {
50 use super::*;
51
52 #[test]
54 #[should_panic]
55 fn normalized_range_checking_iterator_test_maximally_contiguous() {
56 let mut ranges = NormalizedRangeCheckingIterator::new([
57 crate::Range::new(0, 0x1000, crate::Type::FreeRam),
58 crate::Range::new(0x1000, 0x1000, crate::Type::FreeRam),
59 ]);
60
61 ranges.next();
62 ranges.next();
63 }
64
65 #[test]
67 #[should_panic]
68 fn normalized_range_checking_iterator_test_lexicographically_sorted() {
69 let mut ranges = NormalizedRangeCheckingIterator::new([
70 crate::Range::new(0x5000, 0x1000, crate::Type::FreeRam),
71 crate::Range::new(0, 0x1000, crate::Type::FreeRam),
72 ]);
73
74 ranges.next();
75 ranges.next();
76 }
77
78 #[test]
80 #[should_panic]
81 fn normalized_range_checking_iterator_test_non_overlapping() {
82 let mut ranges = NormalizedRangeCheckingIterator::new([
83 crate::Range::new(0, 0x1000, crate::Type::FreeRam),
84 crate::Range::new(0, 0x1000, crate::Type::FreeRam),
85 ]);
86
87 ranges.next();
88 ranges.next();
89 }
90}