1#![deny(missing_docs)]
59#![cfg_attr(coverage_nightly, feature(coverage_attribute))]
61#![cfg_attr(not(test), no_std)]
64extern crate alloc; use smallvec::SmallVec;
67
68mod complement;
69mod intersection;
70mod intersection_iterator;
71pub mod iterator_wrapper;
72mod normalize;
73mod overloads;
74mod primitive_endpoint;
75mod range_case;
76mod range_vec;
77mod slice_sequence;
78mod union;
79mod union_iterator;
80
81pub use range_case::RangeCase;
82pub use range_vec::RangeVec;
83
84pub use normalize::is_normalized;
85pub use normalize::normalize_vec;
86
87pub use complement::complement_vec;
88pub use intersection::intersect_vec;
89pub use union::union_vec;
90
91pub const INLINE_SIZE: usize = if cfg!(feature = "inline_storage") {
97 2
98} else {
99 0
100};
101
102type Backing<T> = SmallVec<[(T, T); INLINE_SIZE]>;
104
105pub trait Endpoint: Copy {
121 fn min_value() -> Self;
125
126 fn max_value() -> Self;
130
131 fn is_valid(self) -> bool;
133
134 fn cmp_end(self, other: Self) -> core::cmp::Ordering;
141
142 #[inline(always)]
148 fn next_after(self) -> Option<Self> {
149 self.increase_toward(Self::max_value())
150 }
151
152 #[inline(always)]
158 fn prev_before(self) -> Option<Self> {
159 self.decrease_toward(Self::min_value())
160 }
161
162 fn decrease_toward(self, other: Self) -> Option<Self>;
172
173 fn increase_toward(self, other: Self) -> Option<Self>;
183
184 #[doc(hidden)]
186 #[inline(always)]
187 fn cmp_range(left: (Self, Self), right: (Self, Self)) -> core::cmp::Ordering {
188 match left.0.cmp_end(right.0) {
189 core::cmp::Ordering::Equal => left.1.cmp_end(right.1),
190 any => any,
191 }
192 }
193
194 #[doc(hidden)]
196 #[inline(always)]
197 fn bot_end(self, other: Self) -> Self {
198 core::cmp::min_by(self, other, |x, y| Self::cmp_end(*x, *y))
199 }
200
201 #[doc(hidden)]
203 #[inline(always)]
204 fn top_end(self, other: Self) -> Self {
205 core::cmp::max_by(self, other, |x, y| Self::cmp_end(*x, *y))
206 }
207}
208
209type Pair<T> = (T, T);
211
212mod private {
213 pub trait Sealed {}
214}
215
216pub trait ClosedRange: Copy + private::Sealed {
227 #[doc(hidden)]
229 type EndT: Endpoint;
230
231 #[doc(hidden)]
234 fn get(self) -> Pair<Self::EndT>;
235}
236
237pub trait NormalizedRangeIter: private::Sealed + Iterator<Item: ClosedRange> {
243 #[inline(always)]
245 #[must_use]
246 fn into_empty_flag(mut self) -> bool
247 where
248 Self: Sized,
249 {
250 self.next().is_none()
251 }
252
253 #[inline(always)]
255 #[must_use]
256 fn into_inhabited_flag(self) -> bool
257 where
258 Self: Sized,
259 {
260 !self.into_empty_flag()
261 }
262
263 #[must_use]
269 fn eqv(
270 mut self,
271 other: impl IntoNormalizedRangeIter<Item: ClosedRange<EndT = ClosedRangeEnd<Self::Item>>>,
272 ) -> bool
273 where
274 Self: Sized,
275 {
276 use core::cmp::Ordering;
277
278 let mut other = other.into_iter();
279 loop {
280 match (self.next(), other.next()) {
282 (Some(a), Some(b)) => {
283 if Endpoint::cmp_range(a.get(), b.get()) != Ordering::Equal {
284 return false;
285 }
286 }
287 (None, None) => return true,
288 _ => return false,
289 }
290 }
291 }
292
293 #[inline(always)]
300 #[must_use]
301 fn complement(self) -> complement::ComplementIterator<Self>
302 where
303 Self: Sized,
304 {
305 complement::ComplementIterator::new(self)
306 }
307
308 #[inline(always)]
317 #[must_use]
318 fn intersect_vec<'a>(
319 self,
320 other: &'a RangeVec<ClosedRangeEnd<Self::Item>>,
321 ) -> intersection::IntersectionIterator<'a, Self>
322 where
323 Self: 'a + Sized,
324 {
325 unsafe { crate::intersection::intersect(self, other) }
327 }
328
329 #[inline(always)]
337 #[must_use]
338 fn intersect<Other>(
339 self,
340 other: Other,
341 ) -> intersection_iterator::LinearIntersectionIterator<
342 ClosedRangeEnd<Self::Item>,
343 Self,
344 <Other as IntoIterator>::IntoIter,
345 >
346 where
347 Self: Sized,
348 Other: IntoNormalizedRangeIter<Item: ClosedRange<EndT = ClosedRangeEnd<Self::Item>>>,
349 {
350 intersection_iterator::LinearIntersectionIterator::new(self, other.into_iter())
351 }
352
353 #[inline(always)]
361 #[must_use]
362 fn union<Other>(
363 self,
364 other: Other,
365 ) -> union_iterator::UnionIterator<
366 ClosedRangeEnd<Self::Item>,
367 Self,
368 <Other as IntoIterator>::IntoIter,
369 >
370 where
371 Self: Sized,
372 Other: IntoNormalizedRangeIter<Item: ClosedRange<EndT = ClosedRangeEnd<Self::Item>>>,
373 {
374 union_iterator::UnionIterator::new(self, other.into_iter())
375 }
376
377 #[must_use]
382 fn collect_range_vec(self) -> RangeVec<ClosedRangeEnd<Self::Item>>
383 where
384 Self: Sized,
385 {
386 #[cfg(feature = "internal_checks")]
387 let hint = self.size_hint();
388
389 let inner: SmallVec<[_; INLINE_SIZE]> = self.map(|range| range.get()).collect();
390
391 #[cfg(feature = "internal_checks")]
392 {
393 assert!(hint.0 <= inner.len());
394 assert!(inner.len() <= hint.1.unwrap_or(usize::MAX));
395 assert!(is_normalized(&inner));
396 }
397
398 unsafe { RangeVec::new_unchecked(inner) }
399 }
400}
401
402impl<T: NormalizedRangeIter + ?Sized> private::Sealed for alloc::boxed::Box<T> {}
404impl<T: NormalizedRangeIter + ?Sized> NormalizedRangeIter for alloc::boxed::Box<T> {}
405
406pub trait IntoNormalizedRangeIter: IntoIterator<IntoIter: NormalizedRangeIter> {}
409
410impl<T: IntoIterator<IntoIter: NormalizedRangeIter>> IntoNormalizedRangeIter for T {}
411
412impl<T: Endpoint> private::Sealed for (T, T) {}
413
414impl<T: Endpoint> ClosedRange for (T, T) {
415 type EndT = T;
416
417 #[inline(always)]
418 fn get(self) -> (T, T) {
419 self
420 }
421}
422
423impl<T: Endpoint> private::Sealed for &(T, T) {}
424
425impl<T: Endpoint> ClosedRange for &(T, T) {
426 type EndT = T;
427
428 #[inline(always)]
429 fn get(self) -> (T, T) {
430 *self
431 }
432}
433
434type ClosedRangeEnd<T> = <T as ClosedRange>::EndT;
436type ClosedRangeVal<T> = Pair<ClosedRangeEnd<T>>;
438
439#[cfg(test)]
440#[cfg_attr(coverage_nightly, coverage(off))]
441fn ranges_to_bits(ranges: &[(u8, u8)]) -> alloc::vec::Vec<bool> {
442 use alloc::vec;
443
444 let mut marks = vec![false; 256];
445
446 for (start, stop) in ranges.iter().copied() {
447 if start <= stop {
448 for i in start..=stop {
449 marks[i as usize] = true;
450 }
451 }
452 }
453
454 marks
455}
456
457#[cfg(test)]
458#[cfg_attr(coverage_nightly, coverage(off))]
459mod test {
460 use super::*;
461 use alloc::vec;
462 use alloc::vec::Vec;
463
464 #[test]
465 fn test_min_max() {
466 assert_eq!(<u8 as Endpoint>::min_value(), 0);
467 assert_eq!(<u8 as Endpoint>::max_value(), 255);
468
469 assert_eq!(<i8 as Endpoint>::min_value(), -128);
470 assert_eq!(<i8 as Endpoint>::max_value(), 127);
471
472 assert_eq!(<i32 as Endpoint>::min_value(), i32::MIN);
473 assert_eq!(<i32 as Endpoint>::max_value(), i32::MAX);
474
475 assert_eq!(<isize as Endpoint>::min_value(), isize::MIN);
476 assert_eq!(<isize as Endpoint>::max_value(), isize::MAX);
477
478 assert_eq!(<usize as Endpoint>::min_value(), usize::MIN);
479 assert_eq!(<usize as Endpoint>::max_value(), usize::MAX);
480 }
481
482 #[test]
483 fn test_prev_next_u64() {
484 assert_eq!(0u64.prev_before(), None);
485 assert_eq!(0u64.next_after(), Some(1));
486
487 assert_eq!(u64::MAX.prev_before(), Some(u64::MAX - 1));
488 assert_eq!(u64::MAX.next_after(), None);
489
490 assert_eq!(0u64.decrease_toward(0u64), None);
491 assert_eq!(0u64.increase_toward(10u64), Some(1));
492
493 assert_eq!(1u64.decrease_toward(0u64), Some(0u64));
494 assert_eq!(1u64.decrease_toward(1u64), None);
495 assert_eq!(1u64.decrease_toward(2u64), None);
496
497 assert_eq!(1u64.increase_toward(0u64), None);
498 assert_eq!(1u64.increase_toward(1u64), None);
499 assert_eq!(1u64.increase_toward(2u64), Some(2u64));
500
501 assert_eq!(u64::MAX.increase_toward(u64::MAX), None);
502 assert_eq!(u64::MAX.decrease_toward(0), Some(u64::MAX - 1));
503 }
504
505 #[test]
506 fn test_closed_range() {
507 let ranges = vec![(1u8, 2u8), (10u8, 4u8)];
508
509 assert_eq!(
510 &ranges.iter().map(ClosedRange::get).collect::<Vec<_>>(),
511 &ranges
512 );
513 assert_eq!(
514 ranges
515 .clone()
516 .into_iter()
517 .map(ClosedRange::get)
518 .collect::<Vec<_>>(),
519 ranges
520 );
521 }
522
523 #[test]
524 fn test_empty_inhabited_iter() {
525 assert!(RangeVec::<u8>::new().into_iter().into_empty_flag());
526 assert!(!RangeVec::<u8>::new().into_iter().into_inhabited_flag());
527
528 assert!(!RangeVec::from_vec(vec![(1u8, 1u8)])
529 .into_iter()
530 .into_empty_flag());
531 assert!(RangeVec::from_vec(vec![(1u8, 1u8)])
532 .into_iter()
533 .into_inhabited_flag());
534 }
535
536 #[test]
537 fn test_chain_boxed_iter() {
538 let mut acc: Option<Box<dyn NormalizedRangeIter<Item = (u8, u8)>>> = None;
539
540 for i in 1u8..=4u8 {
541 let vec = RangeVec::from_vec(vec![(2 * i, 10 * i)]);
542
543 acc = match acc.take() {
544 None => Some(Box::new(vec.into_iter())),
545 Some(acc) if i % 2 == 0 => Some(Box::new(acc.intersect(vec.into_iter()))),
546 Some(acc) => Some(Box::new(acc.intersect_vec(Box::leak(Box::new(vec))))),
547 };
548 }
549
550 let singleton: SmallVec<[(u8, u8); 1]> = smallvec::smallvec![(0, 6)];
552 acc = Some(Box::new(
553 acc.unwrap().union(RangeVec::from_smallvec(singleton)),
554 ));
555
556 let expected = RangeVec::from_vec(vec![(7u8, 7u8), (11u8, 255u8)]);
557 assert!(acc.unwrap().complement().eqv(expected));
558 }
559
560 proptest::proptest! {
561 #[test]
562 fn test_increase(x: u8) {
563 assert_eq!(<u8 as Endpoint>::max_value(), u8::MAX);
564
565 if x != u8::MAX {
566 assert_eq!(x.next_after(), Some(x + 1));
567 } else {
568 assert_eq!(x.next_after(), None);
569 }
570 }
571
572 #[test]
573 fn test_decrease(x: u8) {
574 assert_eq!(<u8 as Endpoint>::min_value(), 0u8);
575
576 if x != 0u8 {
577 assert_eq!(x.prev_before(), Some(x - 1));
578 } else {
579 assert_eq!(x.prev_before(), None);
580 }
581 }
582
583 #[test]
584 fn test_toward(x: u8, y: u8) {
585 let (x, y) = (x.min(y), x.max(y));
586
587 assert_eq!(x.decrease_toward(y), None);
588 assert_eq!(y.increase_toward(x), None);
589
590 if x == y {
591 assert_eq!(x.increase_toward(y), None);
592 assert_eq!(x.decrease_toward(y), None);
593 assert_eq!(y.increase_toward(x), None);
594 assert_eq!(y.decrease_toward(x), None);
595 } else {
596 assert_eq!(x.increase_toward(y), Some(x + 1));
597 assert_eq!(y.decrease_toward(x), Some(y - 1));
598 }
599 }
600
601 #[test]
602 fn test_top_bot(x: u8, y: u8) {
603 assert_eq!(x.bot_end(y), x.min(y));
604 assert_eq!(y.bot_end(x), x.min(y));
605
606 assert_eq!(x.top_end(y), x.max(y));
607 assert_eq!(y.top_end(x), x.max(y));
608 }
609
610 #[test]
611 fn test_cmp(x: u8, y: u8) {
612 assert_eq!(x.cmp_end(y), x.cmp(&y));
613 assert_eq!(y.cmp_end(x), y.cmp(&x));
614 }
615
616 #[test]
617 fn test_cmp_range(x: (u8, u8), y: (u8, u8)) {
618 assert_eq!(u8::cmp_range(x, y), x.cmp(&y));
619 assert_eq!(u8::cmp_range(y, x), y.cmp(&x));
620 }
621
622 #[test]
626 fn test_increase_isize(x: isize) {
627 assert_eq!(<isize as Endpoint>::max_value(), isize::MAX);
628
629 if x != isize::MAX {
630 assert_eq!(x.next_after(), Some(x + 1));
631 } else {
632 assert_eq!(x.next_after(), None);
633 }
634 }
635
636 #[test]
637 fn test_decrease_isize(x: isize) {
638 assert_eq!(<isize as Endpoint>::min_value(), isize::MIN);
639
640 if x != isize::MIN {
641 assert_eq!(x.prev_before(), Some(x - 1));
642 } else {
643 assert_eq!(x.prev_before(), None);
644 }
645 }
646
647 #[test]
648 fn test_toward_isize(x: isize, y: isize) {
649 let (x, y) = (x.min(y), x.max(y));
650
651 assert_eq!(x.decrease_toward(y), None);
652 assert_eq!(y.increase_toward(x), None);
653
654 if x == y {
655 assert_eq!(x.increase_toward(y), None);
656 assert_eq!(x.decrease_toward(y), None);
657 assert_eq!(y.increase_toward(x), None);
658 assert_eq!(y.decrease_toward(x), None);
659 } else {
660 assert_eq!(x.increase_toward(y), Some(x + 1));
661 assert_eq!(y.decrease_toward(x), Some(y - 1));
662 }
663 }
664
665 #[test]
666 fn test_top_bot_isize(x: isize, y: isize) {
667 assert_eq!(x.bot_end(y), x.min(y));
668 assert_eq!(y.bot_end(x), x.min(y));
669
670 assert_eq!(x.top_end(y), x.max(y));
671 assert_eq!(y.top_end(x), x.max(y));
672 }
673
674 #[test]
675 fn test_cmp_isize(x: isize, y: isize) {
676 assert_eq!(x.cmp_end(y), x.cmp(&y));
677 assert_eq!(y.cmp_end(x), y.cmp(&x));
678 }
679
680 #[test]
681 fn test_cmp_range_isize(x: (isize, isize), y: (isize, isize)) {
682 assert_eq!(isize::cmp_range(x, y), x.cmp(&y));
683 assert_eq!(isize::cmp_range(y, x), y.cmp(&x));
684 }
685
686 #[test]
687 fn test_increase_usize(x: usize) {
688 assert_eq!(<usize as Endpoint>::max_value(), usize::MAX);
689
690 if x != usize::MAX {
691 assert_eq!(x.next_after(), Some(x + 1));
692 } else {
693 assert_eq!(x.next_after(), None);
694 }
695 }
696
697 #[test]
698 fn test_decrease_usize(x: usize) {
699 assert_eq!(<usize as Endpoint>::min_value(), 0usize);
700
701 if x != usize::MIN {
702 assert_eq!(x.prev_before(), Some(x - 1));
703 } else {
704 assert_eq!(x.prev_before(), None);
705 }
706 }
707
708 #[test]
709 fn test_toward_usize(x: usize, y: usize) {
710 let (x, y) = (x.min(y), x.max(y));
711
712 assert_eq!(x.decrease_toward(y), None);
713 assert_eq!(y.increase_toward(x), None);
714
715 if x == y {
716 assert_eq!(x.increase_toward(y), None);
717 assert_eq!(x.decrease_toward(y), None);
718 assert_eq!(y.increase_toward(x), None);
719 assert_eq!(y.decrease_toward(x), None);
720 } else {
721 assert_eq!(x.increase_toward(y), Some(x + 1));
722 assert_eq!(y.decrease_toward(x), Some(y - 1));
723 }
724 }
725
726 #[test]
727 fn test_top_bot_usize(x: usize, y: usize) {
728 assert_eq!(x.bot_end(y), x.min(y));
729 assert_eq!(y.bot_end(x), x.min(y));
730
731 assert_eq!(x.top_end(y), x.max(y));
732 assert_eq!(y.top_end(x), x.max(y));
733 }
734
735 #[test]
736 fn test_cmp_usize(x: usize, y: usize) {
737 assert_eq!(x.cmp_end(y), x.cmp(&y));
738 assert_eq!(y.cmp_end(x), y.cmp(&x));
739 }
740
741 #[test]
742 fn test_cmp_range_usize(x: (usize, usize), y: (usize, usize)) {
743 assert_eq!(usize::cmp_range(x, y), x.cmp(&y));
744 assert_eq!(usize::cmp_range(y, x), y.cmp(&x));
745 }
746 }
747}