1use std::ops::Range;
2
3use crate::idx::Idx;
4use crate::moc::{HasMaxDepth, MOCProperties, NonOverlapping, RangeMOCIterator, ZSorted};
5use crate::qty::MocQty;
6
7pub fn not<T, Q, I>(it: I) -> NotRangeIter<T, Q, I>
9where
10 T: Idx,
11 Q: MocQty<T>,
12 I: RangeMOCIterator<T, Qty = Q>,
13{
14 NotRangeIter::new(it)
15}
16
17pub struct NotRangeIter<T, Q, I>
19where
20 T: Idx,
21 Q: MocQty<T>,
22 I: RangeMOCIterator<T, Qty = Q>,
23{
24 it: I,
25 curr: Option<Range<T>>,
26 start: T,
27 n_cells_max: T,
28}
29
30impl<T, Q, I> NotRangeIter<T, Q, I>
31where
32 T: Idx,
33 Q: MocQty<T>,
34 I: RangeMOCIterator<T, Qty = Q>,
35{
36 pub fn new(mut it: I) -> NotRangeIter<T, Q, I> {
37 let n_cells_max = Q::n_cells_max();
38 match it.next() {
39 Some(range) => {
40 if range.start == T::zero() {
41 if range.end == n_cells_max {
42 NotRangeIter {
44 it,
45 curr: None,
46 start: n_cells_max,
47 n_cells_max,
48 }
49 } else {
50 match it.next() {
52 Some(range2) => NotRangeIter {
53 it,
54 curr: Some(range.end..range2.start),
55 start: range2.end,
56 n_cells_max,
57 },
58 None => NotRangeIter {
59 it,
60 curr: Some(range.end..n_cells_max),
61 start: n_cells_max,
62 n_cells_max,
63 },
64 }
65 }
66 } else {
67 NotRangeIter {
69 it,
70 curr: Some(T::zero()..range.start),
71 start: range.end,
72 n_cells_max,
73 }
74 }
75 }
76 None => {
77 NotRangeIter {
79 it,
80 curr: Some(T::zero()..n_cells_max),
81 start: n_cells_max,
82 n_cells_max,
83 }
84 }
85 }
86 }
87}
88
89impl<T, Q, I> HasMaxDepth for NotRangeIter<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.it.depth_max()
97 }
98}
99impl<T, Q, I> ZSorted for NotRangeIter<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 NotRangeIter<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 NotRangeIter<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 NotRangeIter<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 let new = if let Some(r) = self.it.next() {
130 Some(Range {
131 start: std::mem::replace(&mut self.start, r.end),
132 end: r.start,
133 })
134 } else if self.start == self.n_cells_max {
135 None
136 } else {
137 Some(Range {
138 start: std::mem::replace(&mut self.start, self.n_cells_max),
139 end: self.n_cells_max,
140 })
141 };
142 std::mem::replace(&mut self.curr, new)
143 }
144
145 fn size_hint(&self) -> (usize, Option<usize>) {
146 let cur = if self.curr.is_some() { 0 } else { 1 };
147 let size_hint = self.it.size_hint();
148 if let Some(n) = size_hint.1 {
149 (size_hint.0 + cur, Some(n + cur + 1))
151 } else {
152 (size_hint.0 + cur, None)
153 }
154 }
155}
156
157impl<T, Q, I> RangeMOCIterator<T> for NotRangeIter<T, Q, I>
158where
159 T: Idx,
160 Q: MocQty<T>,
161 I: RangeMOCIterator<T, Qty = Q>,
162{
163 type Qty = Q;
164
165 fn peek_last(&self) -> Option<&Range<T>> {
166 None
170 }
171}