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