1use std::{
4 cmp::{self, Ordering},
5 collections::VecDeque,
6 mem,
7 ops::{Index, Range},
8 ptr::slice_from_raw_parts,
9 slice::Iter,
10};
11
12use num::{Integer, One, PrimInt, Zero};
13#[cfg(not(target_arch = "wasm32"))]
14use rayon::iter::{IntoParallelRefIterator, ParallelIterator};
15#[cfg(not(target_arch = "wasm32"))]
16use rayon::prelude::*;
17
18use crate::{idx::Idx, utils};
19
20pub mod ranges2d;
21
22pub trait SNORanges<'a, T: Idx>: Sized {
25 type OwnedRanges: SNORanges<'a, T>;
26
27 type Iter: Iterator<Item = &'a Range<T>>;
28 #[cfg(not(target_arch = "wasm32"))]
29 type ParIter: ParallelIterator<Item = &'a Range<T>>;
30
31 fn is_empty(&self) -> bool;
32
33 fn iter(&'a self) -> Self::Iter;
35
36 #[cfg(not(target_arch = "wasm32"))]
37 fn par_iter(&'a self) -> Self::ParIter;
38
39 fn intersects_range(&self, x: &Range<T>) -> bool;
40 #[cfg(not(target_arch = "wasm32"))]
41 fn par_intersects_range(&'a self, x: &Range<T>) -> bool {
42 self
43 .par_iter()
44 .map(|r| !(x.start >= r.end || x.end <= r.start))
45 .any(|a| a)
46 }
47
48 fn contains_val(&self, x: &T) -> bool;
49
50 fn contains_range(&self, x: &Range<T>) -> bool;
51 #[cfg(not(target_arch = "wasm32"))]
52 fn par_contains_range(&'a self, x: &Range<T>) -> bool {
53 self
54 .par_iter()
55 .map(|r| x.start >= r.start && x.end <= r.end)
56 .any(|a| a)
57 }
58
59 fn range_fraction(&self, x: &Range<T>) -> f64;
65
66 fn contains(&self, rhs: &'a Self) -> bool {
67 for range in rhs.iter() {
70 if !self.contains_range(range) {
71 return false;
72 }
73 }
74 true
75 }
76
77 fn range_sum(&'a self) -> T {
79 let mut sum = T::zero();
80 for Range { start, end } in self.iter() {
81 sum += *end - *start;
82 }
83 sum
84 }
85
86 fn intersects(&self, rhs: &Self) -> bool;
87
88 fn merge(&self, other: &Self, op: impl Fn(bool, bool) -> bool) -> Self::OwnedRanges;
89
90 fn union(&self, other: &Self) -> Self::OwnedRanges;
91 fn intersection(&self, other: &Self) -> Self::OwnedRanges;
96 fn difference(&self, other: &Self) -> Self::OwnedRanges {
103 self.merge(other, |a, b| a && !b)
104 }
105
106 fn complement_with_upper_bound(&self, upper_bound_exclusive: T) -> Self::OwnedRanges;
109
110 fn trailing_zeros(&'a self) -> u8 {
113 let all_vals_or: T = self
114 .iter()
115 .fold(Zero::zero(), |res, x| res | x.start | x.end);
116 all_vals_or.trailing_zeros() as u8
117 }
118
119 #[cfg(not(target_arch = "wasm32"))]
122 fn par_trailing_zeros(&'a self) -> u8 {
123 let all_vals_or: T = self
124 .par_iter()
125 .fold(T::zero, |res, x| res | x.start | x.end)
126 .reduce(T::zero, |a, b| a | b);
127 all_vals_or.trailing_zeros() as u8
128 }
129}
130
131#[derive(Clone, Debug)]
135pub struct Ranges<T: Idx>(pub Box<[Range<T>]>);
136
137impl<T: Idx> Default for Ranges<T> {
138 fn default() -> Self {
139 Ranges(Default::default())
140 }
141}
142
143impl<T: Idx> Ranges<T> {
144 pub fn new_unchecked(data: Vec<Range<T>>) -> Self {
147 Ranges(data.into_boxed_slice())
148 }
149
150 pub fn new_from_sorted(data: Vec<Range<T>>) -> Self {
153 Self::new_unchecked(MergeOverlappingRangesIter::new(data.iter(), None).collect::<Vec<_>>())
154 }
155
156 pub fn new_from(mut data: Vec<Range<T>>) -> Self {
158 #[cfg(not(target_arch = "wasm32"))]
159 data.par_sort_unstable_by(|left, right| left.start.cmp(&right.start));
160 #[cfg(target_arch = "wasm32")]
161 (&mut data).sort_unstable_by(|left, right| left.start.cmp(&right.start));
162 Self::new_from_sorted(data)
163 }
164
165 pub fn as_bytes(&self) -> &[u8] {
166 let offset = self.0.as_ptr().align_offset(mem::align_of::<u8>());
167 assert_eq!(offset, 0);
169 unsafe {
170 std::slice::from_raw_parts(
171 self.0.as_ptr() as *const u8,
172 (self.0.len() << 1) * std::mem::size_of::<T>(),
173 )
174 }
175 }
176
177 }
188
189impl<T: Idx> PartialEq for Ranges<T> {
190 fn eq(&self, other: &Self) -> bool {
191 self.0 == other.0
192 }
193}
194
195impl<T: Idx> Index<usize> for Ranges<T> {
196 type Output = Range<T>;
197
198 fn index(&self, index: usize) -> &Range<T> {
199 &self.0[index]
200 }
201}
202
203impl<'a, T: Idx> SNORanges<'a, T> for Ranges<T> {
204 type OwnedRanges = Self;
205
206 type Iter = Iter<'a, Range<T>>;
207 #[cfg(not(target_arch = "wasm32"))]
208 type ParIter = rayon::slice::Iter<'a, Range<T>>;
209
210 fn is_empty(&self) -> bool {
211 self.0.is_empty()
212 }
213
214 fn iter(&'a self) -> Self::Iter {
215 self.0.iter()
216 }
217
218 #[cfg(not(target_arch = "wasm32"))]
219 fn par_iter(&'a self) -> Self::ParIter {
220 self.0.par_iter()
221 }
222
223 fn intersects_range(&self, x: &Range<T>) -> bool {
224 BorrowedRanges(&self.0).intersects_range(x)
225 }
226
227 fn contains_val(&self, x: &T) -> bool {
228 BorrowedRanges(&self.0).contains_val(x)
229 }
230
231 fn contains_range(&self, x: &Range<T>) -> bool {
232 BorrowedRanges(&self.0).contains_range(x)
233 }
234
235 fn range_fraction(&self, x: &Range<T>) -> f64 {
236 BorrowedRanges(&self.0).range_fraction(x)
237 }
238
239 fn intersects(&self, rhs: &Self) -> bool {
240 BorrowedRanges(&self.0).intersects(&BorrowedRanges(&rhs.0))
241 }
242
243 fn union(&self, other: &Self) -> Self {
244 BorrowedRanges(&self.0).union(&BorrowedRanges(&other.0))
245 }
246
247 fn intersection(&self, other: &Self) -> Self {
248 BorrowedRanges(&self.0).intersection(&BorrowedRanges(&other.0))
249 }
250
251 #[allow(clippy::many_single_char_names)]
252 fn merge(&self, other: &Self, op: impl Fn(bool, bool) -> bool) -> Self {
253 BorrowedRanges(&self.0).merge(&BorrowedRanges(&other.0), op)
254 }
255
256 fn complement_with_upper_bound(&self, upper_bound_exclusive: T) -> Self {
257 BorrowedRanges(&self.0).complement_with_upper_bound(upper_bound_exclusive)
258 }
259}
260
261pub struct BorrowedRanges<'a, T: Idx>(pub &'a [Range<T>]);
263
264impl<'a, T: Idx> From<&'a Ranges<T>> for BorrowedRanges<'a, T> {
265 fn from(ranges: &'a Ranges<T>) -> Self {
266 BorrowedRanges(&ranges.0)
267 }
268}
269
270impl<'a, T: Idx> From<&'a [u8]> for BorrowedRanges<'a, T> {
271 fn from(blob: &'a [u8]) -> Self {
272 let offset = blob.as_ptr().align_offset(mem::align_of::<Range<T>>());
273 if offset != 0 {
274 panic!("Not aligned array!!");
275 }
276 let len = blob.len() / std::mem::size_of::<Range<T>>();
277 debug_assert_eq!(blob.len(), len * std::mem::size_of::<Range<T>>());
278 BorrowedRanges(unsafe { &*slice_from_raw_parts(blob.as_ptr() as *const Range<T>, len) })
279 }
280}
281
282impl<'a, T: Idx> BorrowedRanges<'a, T> {
283 pub fn as_bytes(&self) -> &[u8] {
284 let offset = self.0.as_ptr().align_offset(mem::align_of::<u8>());
285 assert_eq!(offset, 0);
287 unsafe {
288 std::slice::from_raw_parts(
289 self.0.as_ptr() as *const u8,
290 (self.0.len() << 1) * std::mem::size_of::<T>(),
291 )
292 }
293 }
294}
295
296impl<'a, T: Idx> SNORanges<'a, T> for BorrowedRanges<'a, T> {
297 type OwnedRanges = Ranges<T>;
298
299 type Iter = Iter<'a, Range<T>>;
300 #[cfg(not(target_arch = "wasm32"))]
301 type ParIter = rayon::slice::Iter<'a, Range<T>>;
302
303 fn is_empty(&self) -> bool {
304 self.0.is_empty()
305 }
306
307 fn iter(&'a self) -> Self::Iter {
308 self.0.iter()
309 }
310
311 #[cfg(not(target_arch = "wasm32"))]
312 fn par_iter(&'a self) -> Self::ParIter {
313 self.0.par_iter()
314 }
315
316 fn intersects_range(&self, x: &Range<T>) -> bool {
318 let len = self.0.len();
319 if len == 0 || x.end <= self.0[0].start || self.0[len - 1].end <= x.start {
321 return false;
322 }
323 let len = len << 1;
324 let ptr = self.0.as_ptr();
325 let result: &[T] = unsafe { &*slice_from_raw_parts(ptr as *const T, len) };
330 match result.binary_search(&x.start) {
331 Ok(i) => {
332 i & 1 == 0 || (i + 1 < len && x.end > result[i + 1]) }
335 Err(i) => {
336 i & 1 == 1 || (i < len && x.end > result[i]) }
339 }
340 }
341
342 fn contains_val(&self, x: &T) -> bool {
344 let len = self.0.len();
345 if len == 0 || *x < self.0[0].start || self.0[len - 1].end <= *x {
347 return false;
348 }
349 let len = len << 1;
350 let ptr = self.0.as_ptr();
351 let result: &[T] = unsafe { &*slice_from_raw_parts(ptr as *const T, len) };
356 match result.binary_search(x) {
358 Ok(i) => i & 1 == 0, Err(i) => i & 1 == 1, }
361 }
362
363 fn contains_range(&self, x: &Range<T>) -> bool {
365 let len = self.0.len();
366 if len == 0 || x.end <= self.0[0].start || self.0[len - 1].end <= x.start {
368 return false;
369 }
370 let len = len << 1;
371 let ptr = self.0.as_ptr();
372 let result: &[T] = unsafe { &*slice_from_raw_parts(ptr as *const T, len) };
377 match result.binary_search(&x.start) {
379 Ok(i) => i & 1 == 0 && x.end <= result[i | 1], Err(i) => i & 1 == 1 && x.end <= result[i], }
382 }
383
384 fn range_fraction(&self, x: &Range<T>) -> f64 {
388 let mut width = T::zero();
389 let ranges = self.0;
390 if ranges.is_empty() || x.end <= ranges[0].start || ranges[ranges.len() - 1].end <= x.start {
391 0.0
393 } else {
394 let i = match ranges.binary_search_by(|range| range.start.cmp(&x.start)) {
396 Ok(i) => i,
397 Err(i) => {
398 if i > 0 && ranges[i - 1].end > x.start {
399 i - 1
400 } else {
401 i
402 }
403 }
404 };
405 for range in ranges[i..].iter() {
407 if x.end <= range.start {
408 break;
410 } else {
411 let start = range.start.max(x.start);
412 let end = range.end.min(x.end);
413 width += end - start;
414 }
415 }
416 let mut tot = x.end - x.start;
418 if width == T::zero() {
419 0.0
420 } else if width == tot {
421 1.0
422 } else {
423 if tot.unsigned_shr(52) > T::zero() {
425 let shift = T::N_BITS as u32 - tot.unsigned_shr(52).leading_zeros();
429 width = width.unsigned_shr(shift);
430 tot = tot.unsigned_shr(shift);
431 }
432 width.cast_to_f64() / tot.cast_to_f64()
433 }
434 }
435 }
436
437 fn intersects(&self, rhs: &Self) -> bool {
438 let l = &self.0;
440 let r = &rhs.0;
441 if l.is_empty()
443 || r.is_empty()
444 || l[0].start >= r[r.len() - 1].end
445 || l[l.len() - 1].end <= r[0].start
446 {
447 return false;
448 }
449 let (il, ir) = match l[0].start.cmp(&r[0].start) {
451 Ordering::Less => {
452 let il = match l.binary_search_by(|l_range| l_range.start.cmp(&r[0].start)) {
453 Ok(i) => i,
454 Err(i) => i - 1,
455 };
456 (il, 0)
457 }
458 Ordering::Greater => {
459 let ir = match r.binary_search_by(|r_range| r_range.start.cmp(&l[0].start)) {
460 Ok(i) => i,
461 Err(i) => i - 1,
462 };
463 (0, ir)
464 }
465 Ordering::Equal => (0, 0),
466 };
467 let mut left_it = l[il..].iter();
469 let mut right_it = r[ir..].iter();
470 let mut left = left_it.next();
471 let mut right = right_it.next();
472 while let (Some(el), Some(er)) = (&left, &right) {
473 if el.end <= er.start {
474 left = left_it.next();
476 while let Some(el) = &left {
477 if el.end <= er.start {
478 left = left_it.next();
479 } else {
480 break;
481 }
482 }
483 } else if er.end <= el.start {
484 right = right_it.next();
486 while let Some(er) = &right {
487 if er.end <= el.start {
488 right = right_it.next();
489 } else {
490 break;
491 }
492 }
493 } else {
494 return true;
495 }
496 }
497 false
498 }
499
500 #[allow(clippy::many_single_char_names)]
501 fn merge(&self, other: &Self, op: impl Fn(bool, bool) -> bool) -> Self::OwnedRanges {
502 let l = &self.0;
503 let ll = l.len() << 1;
504
505 let r = &other.0;
506 let rl = r.len() << 1;
507
508 let mut i = 0;
509 let mut j = 0;
510
511 let mut result = Vec::with_capacity(ll + rl);
512
513 while i < ll || j < rl {
514 let (in_l, in_r, c) = if i == ll {
515 let rv = if j & 0x1 != 0 {
516 r[j >> 1].end
517 } else {
518 r[j >> 1].start
519 };
520
521 let on_rising_edge_t2 = (j & 0x1) == 0;
522
523 let in_l = false;
524 let in_r = on_rising_edge_t2;
525
526 j += 1;
527
528 (in_l, in_r, rv)
529 } else if j == rl {
530 let lv = if i & 0x1 != 0 {
531 l[i >> 1].end
532 } else {
533 l[i >> 1].start
534 };
535
536 let on_rising_edge_t1 = (i & 0x1) == 0;
537
538 let in_l = on_rising_edge_t1;
539 let in_r = false;
540
541 i += 1;
542
543 (in_l, in_r, lv)
544 } else {
545 let lv = if i & 0x1 != 0 {
546 l[i >> 1].end
547 } else {
548 l[i >> 1].start
549 };
550 let rv = if j & 0x1 != 0 {
551 r[j >> 1].end
552 } else {
553 r[j >> 1].start
554 };
555
556 let on_rising_edge_t1 = (i & 0x1) == 0;
557 let on_rising_edge_t2 = (j & 0x1) == 0;
558
559 let c = cmp::min(lv, rv);
560
561 let in_l = (on_rising_edge_t1 && c == lv) | (!on_rising_edge_t1 && c < lv);
562 let in_r = (on_rising_edge_t2 && c == rv) | (!on_rising_edge_t2 && c < rv);
563
564 if c == lv {
565 i += 1;
566 }
567 if c == rv {
568 j += 1;
569 }
570
571 (in_l, in_r, c)
572 };
573
574 let closed = (result.len() & 0x1) == 0;
575
576 let add = !(closed ^ op(in_l, in_r));
577 if add {
578 result.push(c);
579 }
580 }
581 result.shrink_to_fit();
582 Ranges::new_unchecked(utils::unflatten(&mut result))
583 }
584
585 fn union(&self, other: &Self) -> Self::OwnedRanges {
586 let l = self.0;
587 let r = other.0;
588 if l.is_empty() {
590 return Ranges(r.to_vec().into_boxed_slice());
591 } else if r.is_empty() {
592 return Ranges(l.to_vec().into_boxed_slice());
593 }
594 if l.last().unwrap().end < r.first().unwrap().start {
597 return Ranges::new_unchecked(l.iter().cloned().chain(r.iter().cloned()).collect());
598 } else if r.last().unwrap().end < l.first().unwrap().start {
599 return Ranges::new_unchecked(r.iter().cloned().chain(l.iter().cloned()).collect());
600 }
601 let mut res = Vec::with_capacity(l.len() + r.len());
603 let (il, ir) = if l[0].end < r[0].start {
605 let il = match l.binary_search_by(|l_range| l_range.end.cmp(&r[0].start)) {
606 Ok(i) => i,
607 Err(i) => i,
608 };
609 res.extend_from_slice(&l[..il]);
610 (il, 0)
611 } else if l[0].start > r[0].end {
612 let ir = match r.binary_search_by(|r_range| r_range.end.cmp(&l[0].start)) {
613 Ok(i) => i,
614 Err(i) => i,
615 };
616 res.extend_from_slice(&r[..ir]);
617 (0, ir)
618 } else {
619 (0, 0)
620 };
621 let mut left_it = l[il..].iter();
623 let mut right_it = r[ir..].iter();
624 let mut left = left_it.next().cloned();
625 let mut right = right_it.next().cloned();
626
627 fn consume_while_end_lower_than<'a, T, I>(it: &mut I, to: T) -> Option<&'a Range<T>>
628 where
629 T: Idx,
630 I: Iterator<Item = &'a Range<T>>,
631 {
632 let mut curr = it.next();
633 while let Some(c) = &curr {
634 if c.end > to {
635 break;
636 } else {
637 curr = it.next();
638 }
639 }
640 curr
641 }
642
643 loop {
644 match (&mut left, &mut right) {
645 (Some(ref mut l), Some(ref mut r)) => {
646 if l.end < r.start {
647 res.push(mem::replace(&mut left, left_it.next().cloned()).unwrap());
649 } else if r.end < l.start {
650 res.push(mem::replace(&mut right, right_it.next().cloned()).unwrap());
652 } else if l.end <= r.end {
653 if l.start < r.start {
655 r.start = l.start;
657 }
658 left = consume_while_end_lower_than(&mut left_it, r.end).cloned();
659 } else {
660 if r.start < l.start {
662 l.start = r.start;
664 }
665 right = consume_while_end_lower_than(&mut right_it, l.end).cloned();
666 }
667 }
668 (Some(ref l), None) => {
669 res.push(l.clone());
670 for l in left_it {
671 res.push(l.clone());
672 }
673 break;
674 }
675 (None, Some(ref r)) => {
676 res.push(r.clone());
677 for r in right_it {
678 res.push(r.clone());
679 }
680 break;
681 }
682 (None, None) => break,
683 };
684 }
685 res.shrink_to_fit();
686 Ranges::new_unchecked(res)
687 }
688
689 fn intersection(&self, other: &Self) -> Self::OwnedRanges {
690 let l = &self.0;
692 let r = &other.0;
693 if l.is_empty()
695 || r.is_empty()
696 || l[0].start >= r[r.len() - 1].end
697 || l[l.len() - 1].end <= r[0].start
698 {
699 return Ranges(Default::default());
700 }
701 let (il, ir) = match l[0].start.cmp(&r[0].start) {
703 Ordering::Less => {
704 let il = match l.binary_search_by(|l_range| l_range.start.cmp(&r[0].start)) {
705 Ok(i) => i,
706 Err(i) => i - 1,
707 };
708 (il, 0)
709 }
710 Ordering::Greater => {
711 let ir = match r.binary_search_by(|r_range| r_range.start.cmp(&l[0].start)) {
712 Ok(i) => i,
713 Err(i) => i - 1,
714 };
715 (0, ir)
716 }
717 Ordering::Equal => (0, 0),
718 };
719 let mut res = Vec::with_capacity(l.len() + r.len() - (il + ir));
721 let mut left_it = l[il..].iter();
722 let mut right_it = r[ir..].iter();
723 let mut left = left_it.next();
724 let mut right = right_it.next();
725 while let (Some(el), Some(er)) = (&left, &right) {
726 if el.end <= er.start {
727 left = left_it.next();
729 while let Some(el) = &left {
730 if el.end <= er.start {
731 left = left_it.next();
732 } else {
733 break;
734 }
735 }
736 } else if er.end <= el.start {
737 right = right_it.next();
739 while let Some(er) = &right {
740 if er.end <= el.start {
741 right = right_it.next();
742 } else {
743 break;
744 }
745 }
746 } else {
747 let from = el.start.max(er.start);
748 match el.end.cmp(&er.end) {
749 Ordering::Less => {
750 res.push(from..el.end);
751 left = left_it.next();
752 }
753 Ordering::Greater => {
754 res.push(from..er.end);
755 right = right_it.next();
756 }
757 Ordering::Equal => {
758 res.push(from..el.end);
759 left = left_it.next();
760 right = right_it.next();
761 }
762 }
763 }
764 }
765 res.shrink_to_fit();
766 Ranges::new_unchecked(res)
767 }
768
769 fn complement_with_upper_bound(&self, upper_bound_exclusive: T) -> Self::OwnedRanges {
770 let ranges = &self.0;
771 let mut result = Vec::<Range<T>>::with_capacity(ranges.len() + 1);
772
773 if self.is_empty() {
774 result.push(T::zero()..upper_bound_exclusive);
775 } else {
776 let mut s = 0;
777 let mut last = if ranges[0].start == T::zero() {
778 s = 1;
779 ranges[0].end
780 } else {
781 T::zero()
782 };
783
784 result = ranges
785 .iter()
786 .skip(s)
787 .map(|range| {
788 let r = last..range.start;
789 last = range.end;
790 r
791 })
792 .collect::<Vec<_>>();
793
794 if last < upper_bound_exclusive {
795 result.push(last..upper_bound_exclusive);
796 }
797 }
798 Ranges::new_unchecked(result)
799 }
800}
801
802#[derive(Debug)]
803pub struct MergeOverlappingRangesIter<'a, T>
804where
805 T: Integer,
806{
807 last: Option<Range<T>>,
808 ranges: Iter<'a, Range<T>>,
809 split_ranges: VecDeque<Range<T>>,
810 shift: Option<u32>,
811}
812
813impl<'a, T> MergeOverlappingRangesIter<'a, T>
814where
815 T: Integer + PrimInt,
816{
817 pub fn new(
818 mut ranges: Iter<'a, Range<T>>,
819 shift: Option<u32>,
820 ) -> MergeOverlappingRangesIter<'a, T> {
821 let last = ranges.next().cloned();
822 let split_ranges = VecDeque::<Range<T>>::new();
823 MergeOverlappingRangesIter {
824 last,
825 ranges,
826 split_ranges,
827 shift,
828 }
829 }
830
831 fn split_range(&self, range: Range<T>) -> VecDeque<Range<T>> {
832 let mut ranges = VecDeque::<Range<T>>::new();
833 match self.shift {
834 None => {
835 ranges.push_back(range);
836 }
837 Some(shift) => {
838 let mut mask: T = One::one();
839 mask = mask.unsigned_shl(shift) - One::one();
840
841 if range.end - range.start < mask {
842 ranges.push_back(range);
843 } else {
844 let offset = range.start & mask;
845 let mut s = range.start;
846 if offset > Zero::zero() {
847 s = (range.start - offset) + mask + One::one();
848 ranges.push_back(range.start..s);
849 }
850
851 while s + mask + One::one() < range.end {
852 let next = s + mask + One::one();
853 ranges.push_back(s..next);
854 s = next;
855 }
856
857 ranges.push_back(s..range.end);
858 }
859 }
860 }
861 ranges
862 }
863}
864
865impl<'a, T> Iterator for MergeOverlappingRangesIter<'a, T>
866where
867 T: Integer + PrimInt,
868{
869 type Item = Range<T>;
870
871 fn next(&mut self) -> Option<Self::Item> {
872 if !self.split_ranges.is_empty() {
873 return self.split_ranges.pop_front();
874 }
875
876 while let Some(curr) = self.ranges.next() {
877 let prev = self.last.as_mut().unwrap();
878 if curr.start <= prev.end {
879 prev.end = cmp::max(curr.end, prev.end);
880 } else {
881 let range = self.last.clone();
882 self.last = Some(curr.clone());
883
884 self.split_ranges = self.split_range(range.unwrap());
885 return self.split_ranges.pop_front();
886 }
887 }
888
889 if self.last.is_some() {
890 let range = self.last.clone();
891 self.last = None;
892
893 self.split_ranges = self.split_range(range.unwrap());
894 self.split_ranges.pop_front()
895 } else {
896 None
897 }
898 }
899}
900
901#[cfg(test)]
902mod tests {
903
904 use std::{
905 mem::{align_of, size_of},
906 ops::Range,
907 };
908
909 use num::PrimInt;
910 use rand::Rng;
911
912 use crate::{
913 qty::{Hpx, MocQty},
914 ranges::{Ranges, SNORanges},
915 };
916
917 #[test]
918 fn test_alignment() {
919 assert_eq!(align_of::<u32>(), align_of::<Range<u32>>());
921 assert_eq!(align_of::<u64>(), align_of::<Range<u64>>());
922 assert_eq!(align_of::<i32>(), align_of::<Range<i32>>());
923 assert_eq!(align_of::<i64>(), align_of::<Range<i64>>());
924
925 assert_eq!(size_of::<u32>() << 1, size_of::<Range<u32>>());
926 assert_eq!(size_of::<u64>() << 1, size_of::<Range<u64>>());
927 assert_eq!(size_of::<i32>() << 1, size_of::<Range<i32>>());
928 assert_eq!(size_of::<i64>() << 1, size_of::<Range<i64>>());
929 }
930
931 #[test]
932 fn merge_range() {
933 fn assert_merge(a: Vec<Range<u64>>, expected: Vec<Range<u64>>) {
934 let ranges = Ranges::<u64>::new_from(a);
935 let expected_ranges = Ranges::<u64>::new_unchecked(expected);
936
937 assert_eq!(ranges, expected_ranges);
938 }
939
940 assert_merge(vec![12..17, 3..5, 5..7, 6..8], vec![3..8, 12..17]);
941 assert_merge(vec![0..1, 2..5], vec![0..1, 2..5]);
942 assert_merge(vec![], vec![]);
943 assert_merge(vec![0..6, 7..9, 8..13], vec![0..6, 7..13]);
944 }
945
946 #[test]
947 fn test_union() {
948 fn assert_union(a: Vec<Range<u64>>, b: Vec<Range<u64>>, expected: Vec<Range<u64>>) {
949 let a = Ranges::<u64>::new_from(a);
950 let b = Ranges::<u64>::new_from(b);
951
952 let expected_ranges = Ranges::<u64>::new_unchecked(expected);
953 let ranges = a.union(&b);
954 assert_eq!(ranges, expected_ranges);
955 }
956
957 assert_union(
958 vec![12..17, 3..5, 5..7, 6..8],
959 vec![0..1, 2..5],
960 vec![0..1, 2..8, 12..17],
961 );
962 assert_union(
963 vec![12..17, 3..5, 5..7, 6..8],
964 vec![12..17, 3..5, 5..7, 6..8],
965 vec![3..8, 12..17],
966 );
967 assert_union(vec![], vec![], vec![]);
968 assert_union(vec![12..17], vec![], vec![12..17]);
969 assert_union(vec![], vec![12..17], vec![12..17]);
970 assert_union(vec![0..1, 2..3, 4..5], vec![1..22], vec![0..22]);
971 assert_union(vec![0..10], vec![15..22], vec![0..10, 15..22]);
972 }
973
974 #[test]
975 fn test_intersection() {
976 fn assert_intersection(a: Vec<Range<u64>>, b: Vec<Range<u64>>, expected: Vec<Range<u64>>) {
977 let a = Ranges::<u64>::new_from(a);
978 let b = Ranges::<u64>::new_from(b);
979
980 let expected_ranges = Ranges::<u64>::new_unchecked(expected);
981 let ranges = a.intersection(&b);
982 assert_eq!(ranges, expected_ranges);
983 }
984
985 assert_intersection(vec![12..17, 3..5, 5..7, 6..8], vec![0..1, 2..5], vec![3..5]);
986 assert_intersection(vec![], vec![0..1, 2..5], vec![]);
987 assert_intersection(vec![], vec![], vec![]);
988 assert_intersection(vec![2..6], vec![0..3, 4..8], vec![2..3, 4..6]);
989 assert_intersection(vec![2..6], vec![2..6, 7..8], vec![2..6]);
990 assert_intersection(vec![10..11], vec![10..11], vec![10..11]);
991 }
992
993 #[test]
994 fn test_difference() {
995 fn assert_difference(a: Vec<Range<u64>>, b: Vec<Range<u64>>, expected: Vec<Range<u64>>) {
996 let a = Ranges::<u64>::new_from(a);
997 let b = Ranges::<u64>::new_from(b);
998
999 let expected_ranges = Ranges::<u64>::new_unchecked(expected);
1000 let ranges = a.difference(&b);
1001 assert_eq!(ranges, expected_ranges);
1002 }
1003
1004 assert_difference(vec![0..20], vec![5..7], vec![0..5, 7..20]);
1005 assert_difference(vec![0..20], vec![0..20], vec![]);
1006 assert_difference(vec![0..20], vec![], vec![0..20]);
1007 assert_difference(vec![], vec![0..5], vec![]);
1008 assert_difference(vec![0..20], vec![19..22], vec![0..19]);
1009 assert_difference(vec![0..20], vec![25..27], vec![0..20]);
1010 assert_difference(
1011 vec![0..20],
1012 vec![1..2, 3..4, 5..6],
1013 vec![0..1, 2..3, 4..5, 6..20],
1014 );
1015 }
1016
1017 #[test]
1018 fn test_uniq_decompose() {
1019 macro_rules! uniq_to_pix_depth {
1020 ($t:ty, $size:expr) => {
1021 let mut rng = rand::rng();
1022 (0..$size).for_each(|_| {
1023 let depth = rng.random_range(Range {
1024 start: 0,
1025 end: Hpx::<$t>::MAX_DEPTH,
1026 });
1027
1028 let npix = 12 * 4.pow(depth as u32);
1029 let pix = rng.random_range(Range {
1030 start: 0,
1031 end: npix,
1032 });
1033
1034 let uniq = 4 * 4.pow(depth as u32) + pix;
1035 assert_eq!(Hpx::<$t>::from_uniq_hpx(uniq), (depth, pix));
1036 });
1037 };
1038 }
1039
1040 uniq_to_pix_depth!(u128, 10000);
1041 uniq_to_pix_depth!(u64, 10000);
1042 uniq_to_pix_depth!(u32, 10000);
1043 uniq_to_pix_depth!(u8, 10000);
1044 }
1045
1046 }