linnet/half_edge/subgraph/
full.rs1use std::ops::{Range, RangeFrom, RangeInclusive, RangeTo, RangeToInclusive};
2
3use bitvec::vec::BitVec;
4
5use crate::half_edge::{
6 involution::{Hedge, HedgePair},
7 nodestore::NodeStorageOps,
8 HedgeGraph,
9};
10
11use super::{Inclusion, SubGraph};
12
13#[derive(Clone, Debug, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)]
14pub struct FullOrEmpty {
21 size: isize,
26}
27
28impl FullOrEmpty {
29 pub fn full(size: usize) -> FullOrEmpty {
30 FullOrEmpty {
31 size: size as isize,
32 }
33 }
34 pub fn empty(size: usize) -> FullOrEmpty {
35 FullOrEmpty {
36 size: -(size as isize),
37 }
38 }
39}
40
41impl Inclusion<Hedge> for FullOrEmpty {
42 fn includes(&self, hedge_id: &Hedge) -> bool {
43 (hedge_id.0 as isize) < self.size
44 }
45
46 fn intersects(&self, other: &Hedge) -> bool {
47 (other.0 as isize) < self.size
48 }
49}
50
51impl Inclusion<HedgePair> for FullOrEmpty {
52 fn includes(&self, hedge_id: &HedgePair) -> bool {
53 match hedge_id {
54 HedgePair::Split { source, sink, .. } | HedgePair::Paired { source, sink } => {
55 (source.0 as isize) < self.size && (sink.0 as isize) < self.size
56 }
57 HedgePair::Unpaired { hedge, .. } => (hedge.0 as isize) < self.size,
58 }
59 }
60
61 fn intersects(&self, other: &HedgePair) -> bool {
62 match other {
63 HedgePair::Split { source, sink, .. } | HedgePair::Paired { source, sink } => {
64 (source.0 as isize) < self.size && (sink.0 as isize) < self.size
65 }
66 HedgePair::Unpaired { hedge, .. } => (hedge.0 as isize) < self.size,
67 }
68 }
69}
70
71impl Inclusion<FullOrEmpty> for FullOrEmpty {
72 fn includes(&self, other: &FullOrEmpty) -> bool {
73 self.size == other.size
75 }
76
77 fn intersects(&self, other: &FullOrEmpty) -> bool {
78 self.size == other.size
80 }
81}
82
83impl Inclusion<BitVec> for FullOrEmpty {
84 fn includes(&self, other: &BitVec) -> bool {
85 self.size == other.size() as isize
86 }
87
88 fn intersects(&self, other: &BitVec) -> bool {
89 self.size == other.size() as isize
90 }
91}
92
93impl Inclusion<Range<Hedge>> for FullOrEmpty {
94 fn includes(&self, other: &Range<Hedge>) -> bool {
95 if let Ok(size) = usize::try_from(self.size) {
96 size >= other.end.0
97 } else {
98 other.start >= other.end
99 }
100 }
101
102 fn intersects(&self, other: &Range<Hedge>) -> bool {
103 if let Ok(size) = usize::try_from(self.size) {
104 size >= other.end.0
105 } else {
106 other.start >= other.end
107 }
108 }
109}
110
111impl Inclusion<RangeTo<Hedge>> for FullOrEmpty {
112 fn includes(&self, other: &RangeTo<Hedge>) -> bool {
113 if let Ok(size) = usize::try_from(self.size) {
114 size >= other.end.0
115 } else {
116 false
117 }
118 }
119
120 fn intersects(&self, other: &RangeTo<Hedge>) -> bool {
121 if let Ok(size) = usize::try_from(self.size) {
122 size >= other.end.0
123 } else {
124 false
125 }
126 }
127}
128
129impl Inclusion<RangeToInclusive<Hedge>> for FullOrEmpty {
130 fn includes(&self, other: &RangeToInclusive<Hedge>) -> bool {
131 if let Ok(size) = usize::try_from(self.size) {
132 size > other.end.0
133 } else {
134 false
135 }
136 }
137
138 fn intersects(&self, other: &RangeToInclusive<Hedge>) -> bool {
139 if let Ok(size) = usize::try_from(self.size) {
140 size > other.end.0
141 } else {
142 false
143 }
144 }
145}
146
147impl Inclusion<RangeFrom<Hedge>> for FullOrEmpty {
148 fn includes(&self, other: &RangeFrom<Hedge>) -> bool {
149 if let Ok(size) = usize::try_from(self.size) {
150 size > other.start.0
151 } else {
152 false
153 }
154 }
155
156 fn intersects(&self, other: &RangeFrom<Hedge>) -> bool {
157 if let Ok(size) = usize::try_from(self.size) {
158 size > other.start.0
159 } else {
160 false
161 }
162 }
163}
164
165impl Inclusion<RangeInclusive<Hedge>> for FullOrEmpty {
166 fn includes(&self, other: &RangeInclusive<Hedge>) -> bool {
167 if let Ok(size) = usize::try_from(self.size) {
168 size > other.end().0
169 } else {
170 other.start() > other.end()
171 }
172 }
173
174 fn intersects(&self, other: &RangeInclusive<Hedge>) -> bool {
175 if let Ok(size) = usize::try_from(self.size) {
176 size > other.end().0
177 } else {
178 other.start() > other.end()
179 }
180 }
181}
182
183pub struct RangeHedgeIter {
188 iter: Range<usize>,
190}
191
192impl From<Range<Hedge>> for RangeHedgeIter {
193 fn from(value: Range<Hedge>) -> Self {
194 RangeHedgeIter {
195 iter: value.start.0..value.end.0,
196 }
197 }
198}
199
200impl Iterator for RangeHedgeIter {
201 type Item = Hedge;
202
203 fn next(&mut self) -> Option<Self::Item> {
204 self.iter.next().map(Hedge)
205 }
206}
207
208impl SubGraph for FullOrEmpty {
209 type Base = FullOrEmpty;
210 type BaseIter<'a> = RangeHedgeIter;
211 fn nedges<E, V, H, N: NodeStorageOps<NodeData = V>>(
212 &self,
213 graph: &HedgeGraph<E, V, H, N>,
214 ) -> usize {
215 let mut count = 0;
216 for i in self.included_iter() {
217 if i != graph.inv(i) && self.includes(&graph.inv(i)) {
218 count += 1;
219 }
220 }
221 count / 2
222 }
223
224 fn has_greater(&self, _hedge: Hedge) -> bool {
225 false
226 }
227
228 fn size(&self) -> usize {
229 self.size.unsigned_abs()
230 }
231
232 fn join_mut(&mut self, other: Self) {
233 if self.is_empty() && other.is_empty() {
234 self.size -= other.size
235 } else if !self.is_empty() && !other.is_empty() {
236 self.size += other.size
237 }
238 }
239
240 fn included_iter(&self) -> Self::BaseIter<'_> {
241 if self.is_empty() {
242 (Hedge(1)..Hedge(0)).into()
243 } else {
244 (Hedge(0)..Hedge(self.size as usize)).into()
245 }
246 }
247
248 fn nhedges(&self) -> usize {
249 self.size.try_into().unwrap_or(0)
250 }
251
252 fn empty(size: usize) -> Self {
253 FullOrEmpty {
254 size: -(size as isize),
255 }
256 }
257
258 fn included(&self) -> &FullOrEmpty {
259 self
260 }
261
262 fn string_label(&self) -> String {
263 if self.is_empty() {
264 "∅".into()
265 } else {
266 "full".into()
267 }
268 }
269 fn is_empty(&self) -> bool {
270 self.size <= 0
271 }
272}