1use std::ops::Range;
2
3use crate::idx::Idx;
4use crate::moc::{HasMaxDepth, MOCProperties, NonOverlapping, RangeMOCIterator, ZSorted};
5use crate::qty::MocQty;
6
7pub fn degrade<T, Q, I>(it: I, new_depth: u8) -> DegradeRangeIter<T, Q, I>
9where
10 T: Idx,
11 Q: MocQty<T>,
12 I: RangeMOCIterator<T, Qty = Q>,
13{
14 DegradeRangeIter::new(it, new_depth)
15}
16
17pub struct DegradeRangeIter<T, Q, I>
19where
20 T: Idx,
21 Q: MocQty<T>,
22 I: RangeMOCIterator<T, Qty = Q>,
23{
24 new_depth: u8,
25 rm_bits_mask: T,
27 bits_to_be_rm_mask: T,
28 it: I,
29 curr: Option<Range<T>>,
30}
31
32impl<T, Q, I> DegradeRangeIter<T, Q, I>
33where
34 T: Idx,
35 Q: MocQty<T>,
36 I: RangeMOCIterator<T, Qty = Q>,
37{
38 pub fn new(mut it: I, new_depth: u8) -> DegradeRangeIter<T, Q, I> {
39 if new_depth < it.depth_max() {
40 let shift = Q::shift_from_depth_max(new_depth) as u32;
41 let rm_bits_mask = (!T::zero()).unsigned_shl(shift);
43 let bits_to_be_rm_mask = !rm_bits_mask; let mut curr = it.next();
45 if let Some(cr) = &mut curr {
46 degrade_range(
47 cr,
48 rm_bits_mask,
49 bits_to_be_rm_mask,
50 )
51 }
52 DegradeRangeIter {
53 new_depth,
54 rm_bits_mask,
56 bits_to_be_rm_mask,
57 it,
58 curr,
59 }
60 } else {
61 let new_depth = it.depth_max();
63 let curr = it.next();
64 DegradeRangeIter {
65 new_depth,
66 rm_bits_mask: !T::zero(),
68 bits_to_be_rm_mask: T::zero(),
69 it,
70 curr,
71 }
72 }
73 }
74}
75
76#[inline(always)]
77pub(crate) fn degrade_range<T: Idx>(
78 range: &mut Range<T>,
79 rm_bits_mask: T,
80 bits_to_be_rm_mask: T,
81) {
82 range.start &= rm_bits_mask;
83 range.end = (range.end + bits_to_be_rm_mask) & rm_bits_mask
87}
88
89impl<T, Q, I> HasMaxDepth for DegradeRangeIter<T, Q, I>
90where
91 T: Idx,
92 Q: MocQty<T>,
93 I: RangeMOCIterator<T, Qty = Q>,
94{
95 fn depth_max(&self) -> u8 {
96 self.new_depth
97 }
98}
99impl<T, Q, I> ZSorted for DegradeRangeIter<T, Q, I>
100where
101 T: Idx,
102 Q: MocQty<T>,
103 I: RangeMOCIterator<T, Qty = Q>,
104{
105}
106impl<T, Q, I> NonOverlapping for DegradeRangeIter<T, Q, I>
107where
108 T: Idx,
109 Q: MocQty<T>,
110 I: RangeMOCIterator<T, Qty = Q>,
111{
112}
113impl<T, Q, I> MOCProperties for DegradeRangeIter<T, Q, I>
114where
115 T: Idx,
116 Q: MocQty<T>,
117 I: RangeMOCIterator<T, Qty = Q>,
118{
119}
120impl<T, Q, I> Iterator for DegradeRangeIter<T, Q, I>
121where
122 T: Idx,
123 Q: MocQty<T>,
124 I: RangeMOCIterator<T, Qty = Q>,
125{
126 type Item = Range<T>;
127
128 fn next(&mut self) -> Option<Self::Item> {
129 if let Some(cr) = &mut self.curr {
130 let mut next = self.it.next();
131 while let Some(nr) = &mut next {
132 degrade_range(
133 nr,
134 self.rm_bits_mask,
135 self.bits_to_be_rm_mask,
136 );
137 if nr.start > cr.end {
138 break;
139 } else {
140 cr.end = nr.end;
141 next = self.it.next();
142 }
143 }
144 std::mem::replace(&mut self.curr, next)
145 } else {
146 None
147 }
148 }
149
150 }
153
154impl<T, Q, I> RangeMOCIterator<T> for DegradeRangeIter<T, Q, I>
155where
156 T: Idx,
157 Q: MocQty<T>,
158 I: RangeMOCIterator<T, Qty = Q>,
159{
160 type Qty = Q;
161
162 fn peek_last(&self) -> Option<&Range<T>> {
163 None
166 }
167}