1use crate::slice_sequence::Sequence;
2use crate::ClosedRange;
3use crate::ClosedRangeEnd;
4use crate::ClosedRangeVal;
5use crate::Endpoint;
6use crate::NormalizedRangeIter;
7use crate::Pair;
8use crate::RangeVec;
9
10struct IntersectorImpl<Seq: Sequence> {
17 seq: Seq,
18 search_cursor: Seq,
19 intersect_cursor: Seq,
20}
21
22impl<Seq: Sequence> IntersectorImpl<Seq> {
23 #[inline(always)]
24 fn new(seq: Seq) -> Self {
25 Self {
26 seq,
27 search_cursor: seq,
28 intersect_cursor: seq,
29 }
30 }
31
32 #[inline(always)]
33 fn start_search(&mut self, start: Seq::EndT) {
34 self.search_cursor = self.seq.skip_to((start, start), self.search_cursor);
35 self.intersect_cursor = self.search_cursor;
36 }
37
38 fn pump(&mut self, needle: Pair<Seq::EndT>) -> Option<Pair<Seq::EndT>> {
39 use core::cmp::Ordering;
41
42 let (x_start, x_stop) = needle;
43
44 while let Some(((y_start, y_stop), rest)) = self.intersect_cursor.uncons() {
45 self.intersect_cursor = rest;
46
47 if y_start.cmp_end(x_stop) == Ordering::Greater {
48 return None;
49 }
50
51 let start = x_start.top_end(y_start);
52 let stop = x_stop.bot_end(y_stop);
53
54 if start.cmp_end(stop) <= Ordering::Equal {
55 return Some((start, stop));
56 }
57 }
58
59 None
60 }
61}
62
63#[repr(transparent)]
64pub struct Intersector<'a, T: Endpoint>(IntersectorImpl<&'a [(T, T)]>);
65
66impl<'a, T: Endpoint> Intersector<'a, T> {
67 #[inline(always)]
68 fn new(seq: &'a [(T, T)]) -> Self {
69 Self(IntersectorImpl::new(seq))
70 }
71
72 #[inline(always)]
73 fn start_search(&mut self, start: T) {
74 self.0.start_search(start)
75 }
76
77 #[inline(always)]
78 fn pump(&mut self, needle: (T, T)) -> Option<(T, T)> {
79 self.0.pump(needle)
80 }
81}
82
83pub struct IntersectionIterator<'a, Xs: NormalizedRangeIter> {
84 xs: Xs,
87 intersector: Intersector<'a, ClosedRangeEnd<<Xs as Iterator>::Item>>,
88 curr: Option<ClosedRangeVal<<Xs as Iterator>::Item>>,
89}
90
91impl<'a, Xs: NormalizedRangeIter> IntersectionIterator<'a, Xs> {
92 #[inline(always)]
93 fn new(xs: Xs, ys: &'a [ClosedRangeVal<<Xs as Iterator>::Item>]) -> Self {
94 Self {
95 xs,
96 intersector: Intersector::new(ys),
97 curr: None,
98 }
99 }
100}
101
102impl<Xs: NormalizedRangeIter> Iterator for IntersectionIterator<'_, Xs> {
103 type Item = ClosedRangeVal<<Xs as Iterator>::Item>;
104
105 fn next(&mut self) -> Option<Self::Item> {
106 loop {
107 let curr = match self.curr {
108 Some(curr) => curr,
109 None => {
110 let next = self.xs.next()?.get();
111 self.intersector.start_search(next.0);
112 self.curr = Some(next);
113 next
114 }
115 };
116
117 if let Some(ret) = self.intersector.pump(curr) {
118 return Some(ret);
119 }
120
121 self.curr = None;
122 }
123 }
124
125 #[inline]
126 fn size_hint(&self) -> (usize, Option<usize>) {
127 let (_, x_max) = self.xs.size_hint();
130 let y_max = self.intersector.0.search_cursor.len();
131
132 if (x_max == Some(0)) | (y_max == 0) {
133 (0, Some(0))
134 } else {
135 (0, x_max.unwrap_or(usize::MAX).checked_add(y_max))
136 }
137 }
138}
139
140impl<Xs: NormalizedRangeIter> crate::private::Sealed for IntersectionIterator<'_, Xs> {}
141
142impl<Xs: NormalizedRangeIter> crate::NormalizedRangeIter for IntersectionIterator<'_, Xs> {}
143
144impl<Xs: NormalizedRangeIter + core::iter::FusedIterator> core::iter::FusedIterator
145 for IntersectionIterator<'_, Xs>
146{
147}
148
149#[inline(always)]
151pub(crate) unsafe fn intersect<Xs: NormalizedRangeIter>(
152 xs: Xs,
153 ys: &[ClosedRangeVal<<Xs as Iterator>::Item>],
154) -> IntersectionIterator<'_, Xs> {
155 IntersectionIterator::new(xs, ys)
156}
157
158impl<T: Endpoint> RangeVec<T> {
159 #[inline(always)]
165 #[must_use]
166 pub fn intersect_vec<'a>(&'a self, other: &'a RangeVec<T>) -> Self {
167 intersect_vec(self, other)
168 }
169}
170#[inline(never)]
180#[must_use]
181pub fn intersect_vec<'a, T: Endpoint>(
182 mut xs: &'a RangeVec<T>,
183 mut ys: &'a RangeVec<T>,
184) -> RangeVec<T> {
185 #[cfg(feature = "internal_checks")]
186 let expected = (
187 xs.iter().intersect(ys.iter()).collect_range_vec(),
188 ys.iter().intersect(xs.iter()).collect_range_vec(),
189 xs.iter().intersect_vec(ys).collect_range_vec(),
190 ys.iter().intersect_vec(xs).collect_range_vec(),
191 );
192
193 if xs.len() > ys.len() {
194 core::mem::swap(&mut xs, &mut ys);
195 }
196
197 debug_assert!(xs.len() <= ys.len());
198 let intersection = xs.iter().intersect_vec(ys);
199 let size_hint = intersection.size_hint();
200
201 let ret = intersection.collect_range_vec();
202
203 debug_assert!((!(xs.is_empty() | ys.is_empty())) | (size_hint == (0, Some(0))));
205 debug_assert!(size_hint.0 <= ret.len());
206 debug_assert!(ret.len() <= size_hint.1.unwrap());
207
208 #[cfg(feature = "internal_checks")]
209 {
210 assert!(&expected.0.eqv(&ret));
211 assert!(&expected.1.eqv(&ret));
212 assert!(&expected.2.eqv(&ret));
213 assert!(&expected.3.eqv(&ret));
214 }
215
216 ret
217}
218
219#[cfg(test)]
220#[cfg_attr(coverage_nightly, coverage(off))]
221mod test {
222 use super::*;
223 use alloc::vec;
224 use alloc::vec::Vec;
225
226 #[test]
227 fn test_smoke() {
228 assert!(crate::normalize_vec(Vec::<(u8, u8)>::new())
230 .iter()
231 .intersect_vec(&crate::normalize_vec(Vec::<(u8, u8)>::new()))
232 .collect_range_vec()
233 .is_empty());
234
235 let xs = crate::normalize_vec(vec![(1u8, 1u8), (3u8, 4u8), (10u8, 20u8), (30u8, 100u8)]);
236 let ys = crate::normalize_vec(vec![
237 (0u8, 6u8),
238 (8u8, 15u8),
239 (17u8, 18u8),
240 (20u8, 22u8),
241 (200u8, 200u8),
242 ]);
243
244 assert!(crate::normalize_vec(Vec::<(u8, u8)>::new())
246 .iter()
247 .intersect_vec(&xs)
248 .collect_range_vec()
249 .is_empty());
250 assert!(ys
251 .clone()
252 .intersect(&crate::normalize_vec(Vec::<(u8, u8)>::new()))
253 .is_empty());
254
255 assert_eq!(
256 xs.clone().intersect(&ys).into_vec(),
257 vec![
258 (1u8, 1u8),
259 (3u8, 4u8),
260 (10u8, 15u8),
261 (17u8, 18u8),
262 (20u8, 20u8)
263 ]
264 );
265
266 assert_eq!(
267 xs.intersect_vec(&ys).into_vec(),
268 vec![
269 (1u8, 1u8),
270 (3u8, 4u8),
271 (10u8, 15u8),
272 (17u8, 18u8),
273 (20u8, 20u8)
274 ]
275 );
276
277 assert_eq!(
278 intersect_vec(&ys, &xs).into_vec(),
279 vec![
280 (1u8, 1u8),
281 (3u8, 4u8),
282 (10u8, 15u8),
283 (17u8, 18u8),
284 (20u8, 20u8)
285 ]
286 );
287
288 assert_eq!(
289 xs.iter().intersect_vec(&ys).collect::<Vec<_>>(),
290 vec![
291 (1u8, 1u8),
292 (3u8, 4u8),
293 (10u8, 15u8),
294 (17u8, 18u8),
295 (20u8, 20u8)
296 ]
297 );
298
299 assert_eq!(
300 ys.iter().intersect_vec(&xs).collect::<Vec<_>>(),
301 vec![
302 (1u8, 1u8),
303 (3u8, 4u8),
304 (10u8, 15u8),
305 (17u8, 18u8),
306 (20u8, 20u8)
307 ]
308 );
309
310 assert_eq!(
311 intersect_vec(
312 &crate::normalize_vec(xs[..0].to_vec()),
313 &crate::normalize_vec(vec![])
314 )
315 .into_vec(),
316 vec![]
317 );
318
319 {
320 let empty = crate::normalize_vec(xs[..0].to_vec());
321
322 assert_eq!(
323 unsafe { intersect(empty.iter(), &[]) }
324 .collect_range_vec()
325 .into_vec(),
326 vec![]
327 );
328 }
329
330 assert_eq!(
331 intersect_vec(
332 &crate::normalize_vec(xs[1..2].to_vec()),
333 &crate::normalize_vec(vec![(0u8, 0u8)])
334 )
335 .into_vec(),
336 vec![]
337 );
338 }
339
340 proptest::proptest! {
341 #[test]
342 fn test_intersection(xs: Vec<(u8, u8)>, ys: Vec<(u8, u8)>)
343 {
344 use crate::ranges_to_bits;
345
346 let bits = {
347 let x_bits = ranges_to_bits(&xs);
348 let y_bits = ranges_to_bits(&ys);
349
350 x_bits.into_iter().zip(y_bits.into_iter()).map(|(x, y)| x & y).collect::<Vec<bool>>()
351 };
352
353 {
354 let out = intersect_vec(&RangeVec::from_vec(xs.clone()),
355 &RangeVec::from_vec(ys.clone()));
356 assert_eq!(&bits, &ranges_to_bits(&out));
357 }
358
359 {
360 let out = RangeVec::from_vec(ys.clone()).intersect(&RangeVec::from_vec(xs.clone()));
361 assert_eq!(&bits, &ranges_to_bits(&out));
362 }
363
364 {
365 let out = RangeVec::from_vec(xs.clone()).into_iter().intersect_vec(&RangeVec::from_vec(ys.clone())).collect_range_vec();
366 assert_eq!(&bits, &ranges_to_bits(&out));
367 }
368
369 {
370 let out = RangeVec::from_vec(ys.clone()).into_iter().intersect_vec(&RangeVec::from_vec(xs.clone())).collect_range_vec();
371 assert_eq!(&bits, &ranges_to_bits(&out));
372 }
373 }
374
375 #[test]
376 fn test_intersection_identity(xs: Vec<(u8, u8)>, ys: Vec<(u8, u8)>)
377 {
378 let xs = RangeVec::from_vec(xs.into_iter().map(|(a, b)| (a.min(b), a.max(b))).collect::<Vec<_>>());
380 let ys = RangeVec::from_vec(ys.into_iter().map(|(a, b)| (a.min(b), a.max(b))).collect::<Vec<_>>());
381
382 {
388 let not_and = xs.iter().intersect_vec(&ys).complement().collect_range_vec();
389 let or_not = crate::union_vec(xs.iter().complement().collect_range_vec(),
390 ys.iter().complement());
391
392 assert_eq!(not_and, or_not);
393 }
394
395 {
396 let and = xs.iter().intersect_vec(&ys).collect_range_vec();
397 let not_or_not = crate::union_vec(xs.iter().complement().collect_range_vec(),
398 ys.iter().complement()).iter().complement().collect_range_vec();
399
400 assert_eq!(and, not_or_not);
401 }
402
403 {
405 let not_and = intersect_vec(&xs, &ys).into_complement();
406 let or_not = crate::union_vec(xs.clone().into_complement(),
407 ys.clone().into_complement());
408
409 assert_eq!(not_and, or_not);
410 }
411
412 {
413 let not_and = intersect_vec(&xs, &ys).into_complement();
414 let or_not = xs.clone().into_complement().union(
415 ys.clone().into_complement());
416
417 assert_eq!(not_and, or_not);
418 }
419
420 {
421 let and = intersect_vec(&xs, &ys);
422 let not_or_not = xs.clone().into_complement()
423 .union(ys.clone().into_complement())
424 .into_complement();
425
426 assert_eq!(and, not_or_not);
427 }
428 }
429 }
430}