use std::ops::{
BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Range, RangeBounds, Sub,
SubAssign,
};
use crate::{
interval_map::{IntervalMap, IntoIter, Iter},
IndexType,
};
#[derive(Debug, Clone)]
pub struct IntervalSet<Ix = u32> {
inner: IntervalMap<Ix, ()>,
}
impl<Ix: IndexType> Default for IntervalSet<Ix> {
fn default() -> Self {
Self::new()
}
}
impl<Ix: IndexType> IntervalSet<Ix> {
#[inline]
pub fn new() -> Self {
IntervalSet {
inner: IntervalMap::new(),
}
}
#[inline]
pub fn len(&self) -> usize {
self.inner.len()
}
#[inline]
pub fn is_empty(&self) -> bool {
self.inner.is_empty()
}
#[inline]
pub fn clear(&mut self) {
self.inner.clear();
}
#[inline]
pub fn contains(&self, point: Ix) -> bool {
self.inner.contains(point)
}
pub fn get_interval(&self, point: Ix) -> Option<Range<Ix>> {
self.inner.get_interval(point).map(|(range, _)| range)
}
pub fn iter(&self) -> IterSet<'_, Ix> {
IterSet {
inner: self.inner.iter(),
}
}
pub fn first(&self) -> Option<Range<Ix>> {
self.inner.first().map(|(range, _)| range)
}
pub fn last(&self) -> Option<Range<Ix>> {
self.inner.last().map(|(range, _)| range)
}
pub fn span(&self) -> Option<Range<Ix>> {
self.inner.span()
}
}
impl<Ix: IndexType + num_traits::One + num_traits::Bounded> IntervalSet<Ix> {
pub fn overlaps<R: RangeBounds<Ix>>(&self, range: R) -> bool {
self.inner.overlaps(range)
}
pub fn covers<R: RangeBounds<Ix>>(&self, range: R) -> bool {
self.inner.covers(range)
}
pub fn insert<R: RangeBounds<Ix>>(&mut self, range: R) {
self.inner.insert(range, ());
}
pub fn remove<R: RangeBounds<Ix>>(&mut self, range: R) {
self.inner.remove(range);
}
pub fn union(&self, other: &Self) -> Self {
let mut result = self.clone();
for interval in other.iter() {
result.insert(interval);
}
result
}
pub fn intersection(&self, other: &Self) -> Self {
let mut result = IntervalSet::new();
let mut iter_a = self.iter().peekable();
let mut iter_b = other.iter().peekable();
while let (Some(a), Some(b)) = (iter_a.peek(), iter_b.peek()) {
let start = a.start.max(b.start);
let end = a.end.min(b.end);
if start < end {
result.insert(start..end);
}
if a.end <= b.end {
iter_a.next();
}
else {
iter_b.next();
}
}
result
}
pub fn difference(&self, other: &Self) -> Self {
let mut result = self.clone();
for interval in other.iter() {
result.remove(interval);
}
result
}
pub fn symmetric_difference(&self, other: &Self) -> Self {
let a_minus_b = self.difference(other);
let b_minus_a = other.difference(self);
a_minus_b.union(&b_minus_a)
}
pub fn gaps(&self) -> Gaps<'_, Ix> {
Gaps {
inner: self.inner.iter(),
prev_end: None,
}
}
pub fn iter_overlapping<R: RangeBounds<Ix>>(&self, range: R) -> IterOverlapping<'_, Ix> {
IterOverlapping::new(&self.inner, range)
}
pub fn retain<F: FnMut(&Range<Ix>) -> bool>(&mut self, mut f: F) {
let keys_to_remove: Vec<Ix> = self
.inner
.iter()
.filter_map(|(range, _)| {
if !f(&range) {
Some(range.start)
}
else {
None
}
})
.collect();
for key in keys_to_remove {
self.inner.remove_by_start(key);
}
}
pub fn split_at(&mut self, point: Ix) {
self.inner.split_at(point);
}
}
pub struct IterSet<'a, Ix> {
inner: Iter<'a, Ix, ()>,
}
impl<'a, Ix: IndexType> Iterator for IterSet<'a, Ix> {
type Item = Range<Ix>;
fn next(&mut self) -> Option<Self::Item> {
self.inner.next().map(|(range, _)| range)
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.inner.size_hint()
}
}
impl<Ix: IndexType> ExactSizeIterator for IterSet<'_, Ix> {}
impl<'a, Ix: IndexType> IntoIterator for &'a IntervalSet<Ix> {
type Item = Range<Ix>;
type IntoIter = IterSet<'a, Ix>;
fn into_iter(self) -> Self::IntoIter {
IterSet {
inner: self.inner.iter(),
}
}
}
pub struct IntoIterSet<Ix> {
inner: IntoIter<Ix, ()>,
}
impl<Ix: IndexType> Iterator for IntoIterSet<Ix> {
type Item = Range<Ix>;
fn next(&mut self) -> Option<Self::Item> {
self.inner.next().map(|(range, _)| range)
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.inner.size_hint()
}
}
impl<Ix: IndexType> ExactSizeIterator for IntoIterSet<Ix> {}
impl<Ix: IndexType> IntoIterator for IntervalSet<Ix> {
type Item = Range<Ix>;
type IntoIter = IntoIterSet<Ix>;
fn into_iter(self) -> Self::IntoIter {
IntoIterSet {
inner: self.inner.into_iter(),
}
}
}
pub struct Gaps<'a, Ix> {
inner: Iter<'a, Ix, ()>,
prev_end: Option<Ix>,
}
impl<'a, Ix: IndexType> Iterator for Gaps<'a, Ix> {
type Item = Range<Ix>;
fn next(&mut self) -> Option<Self::Item> {
loop {
let (range, _) = self.inner.next()?;
match self.prev_end {
None => {
self.prev_end = Some(range.end);
}
Some(prev_end) => {
self.prev_end = Some(range.end);
if prev_end < range.start {
return Some(prev_end..range.start);
}
}
}
}
}
}
pub struct IterOverlapping<'a, Ix: IndexType> {
inner: Iter<'a, Ix, ()>,
range_start: Ix,
range_end: Ix,
started: bool,
}
impl<'a, Ix: IndexType + num_traits::One + num_traits::Bounded> IterOverlapping<'a, Ix> {
fn new<R: RangeBounds<Ix>>(map: &'a IntervalMap<Ix, ()>, range: R) -> Self {
use std::ops::Bound;
let range_start = match range.start_bound() {
Bound::Included(&s) => s,
Bound::Excluded(&s) => s + Ix::one(),
Bound::Unbounded => Ix::min_value(),
};
let range_end = match range.end_bound() {
Bound::Included(&e) => e + Ix::one(),
Bound::Excluded(&e) => e,
Bound::Unbounded => Ix::max_value(),
};
IterOverlapping {
inner: map.iter(),
range_start,
range_end,
started: false,
}
}
}
impl<'a, Ix: IndexType> Iterator for IterOverlapping<'a, Ix> {
type Item = Range<Ix>;
fn next(&mut self) -> Option<Self::Item> {
if self.range_start >= self.range_end {
return None;
}
loop {
let (interval, _) = self.inner.next()?;
if interval.end <= self.range_start {
continue;
}
if interval.start >= self.range_end {
return None;
}
self.started = true;
return Some(interval);
}
}
}
impl<Ix: IndexType + num_traits::One + num_traits::Bounded> BitOr<&IntervalSet<Ix>>
for &IntervalSet<Ix>
{
type Output = IntervalSet<Ix>;
fn bitor(self, other: &IntervalSet<Ix>) -> Self::Output {
self.union(other)
}
}
impl<Ix: IndexType + num_traits::One + num_traits::Bounded> BitAnd<&IntervalSet<Ix>>
for &IntervalSet<Ix>
{
type Output = IntervalSet<Ix>;
fn bitand(self, other: &IntervalSet<Ix>) -> Self::Output {
self.intersection(other)
}
}
impl<Ix: IndexType + num_traits::One + num_traits::Bounded> Sub<&IntervalSet<Ix>>
for &IntervalSet<Ix>
{
type Output = IntervalSet<Ix>;
fn sub(self, other: &IntervalSet<Ix>) -> Self::Output {
self.difference(other)
}
}
impl<Ix: IndexType + num_traits::One + num_traits::Bounded> BitXor<&IntervalSet<Ix>>
for &IntervalSet<Ix>
{
type Output = IntervalSet<Ix>;
fn bitxor(self, other: &IntervalSet<Ix>) -> Self::Output {
self.symmetric_difference(other)
}
}
impl<Ix: IndexType + num_traits::One + num_traits::Bounded> BitOrAssign<&IntervalSet<Ix>>
for IntervalSet<Ix>
{
fn bitor_assign(&mut self, other: &IntervalSet<Ix>) {
for interval in other.iter() {
self.insert(interval);
}
}
}
impl<Ix: IndexType + num_traits::One + num_traits::Bounded> BitAndAssign<&IntervalSet<Ix>>
for IntervalSet<Ix>
{
fn bitand_assign(&mut self, other: &IntervalSet<Ix>) {
*self = self.intersection(other);
}
}
impl<Ix: IndexType + num_traits::One + num_traits::Bounded> SubAssign<&IntervalSet<Ix>>
for IntervalSet<Ix>
{
fn sub_assign(&mut self, other: &IntervalSet<Ix>) {
for interval in other.iter() {
self.remove(interval);
}
}
}
impl<Ix: IndexType + num_traits::One + num_traits::Bounded> BitXorAssign<&IntervalSet<Ix>>
for IntervalSet<Ix>
{
fn bitxor_assign(&mut self, other: &IntervalSet<Ix>) {
*self = self.symmetric_difference(other);
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_interval_set_insert_and_merge() {
let mut set = IntervalSet::new();
set.insert(0..10);
set.insert(5..15);
assert_eq!(set.len(), 1);
assert!(set.contains(0));
assert!(set.contains(14));
assert!(!set.contains(15));
}
#[test]
fn test_interval_set_adjacent_merge() {
let mut set = IntervalSet::new();
set.insert(0..10);
set.insert(10..20);
assert_eq!(set.len(), 1);
assert!(set.contains(0));
assert!(set.contains(15));
assert!(!set.contains(20));
}
#[test]
fn test_interval_set_non_overlapping() {
let mut set = IntervalSet::new();
set.insert(0..10);
set.insert(20..30);
assert_eq!(set.len(), 2);
assert!(set.contains(5));
assert!(!set.contains(15));
assert!(set.contains(25));
}
#[test]
fn test_interval_set_iter() {
let mut set = IntervalSet::new();
set.insert(0..10);
set.insert(20..30);
let intervals: Vec<_> = set.iter().collect();
assert_eq!(intervals, vec![0..10, 20..30]);
}
#[test]
fn test_interval_set_remove() {
let mut set = IntervalSet::new();
set.insert(0..20);
set.remove(5..15);
assert_eq!(set.len(), 2);
assert!(set.contains(3));
assert!(!set.contains(10));
assert!(set.contains(17));
}
#[test]
fn test_interval_set_into_iter() {
let mut set = IntervalSet::new();
set.insert(0..10);
set.insert(20..30);
let intervals: Vec<_> = set.into_iter().collect();
assert_eq!(intervals, vec![0..10, 20..30]);
}
#[test]
fn test_first_empty() {
let set: IntervalSet<u32> = IntervalSet::new();
assert_eq!(set.first(), None);
}
#[test]
fn test_first_single() {
let mut set = IntervalSet::new();
set.insert(10..20);
assert_eq!(set.first(), Some(10..20));
}
#[test]
fn test_first_multiple() {
let mut set = IntervalSet::new();
set.insert(20..30);
set.insert(5..10);
set.insert(40..50);
assert_eq!(set.first(), Some(5..10));
}
#[test]
fn test_last_empty() {
let set: IntervalSet<u32> = IntervalSet::new();
assert_eq!(set.last(), None);
}
#[test]
fn test_last_single() {
let mut set = IntervalSet::new();
set.insert(10..20);
assert_eq!(set.last(), Some(10..20));
}
#[test]
fn test_last_multiple() {
let mut set = IntervalSet::new();
set.insert(20..30);
set.insert(5..10);
set.insert(40..50);
assert_eq!(set.last(), Some(40..50));
}
#[test]
fn test_span_empty() {
let set: IntervalSet<u32> = IntervalSet::new();
assert_eq!(set.span(), None);
}
#[test]
fn test_span_single() {
let mut set = IntervalSet::new();
set.insert(10..20);
assert_eq!(set.span(), Some(10..20));
}
#[test]
fn test_span_multiple() {
let mut set = IntervalSet::new();
set.insert(5..10);
set.insert(20..30);
set.insert(40..50);
assert_eq!(set.span(), Some(5..50));
}
#[test]
fn test_overlaps_empty() {
let set: IntervalSet<u32> = IntervalSet::new();
assert!(!set.overlaps(0..10));
}
#[test]
fn test_overlaps_no_overlap() {
let mut set = IntervalSet::new();
set.insert(10..20);
assert!(!set.overlaps(0..5));
assert!(!set.overlaps(25..30));
assert!(!set.overlaps(0..10)); assert!(!set.overlaps(20..30)); }
#[test]
fn test_overlaps_partial() {
let mut set = IntervalSet::new();
set.insert(10..20);
assert!(set.overlaps(5..15));
assert!(set.overlaps(15..25));
}
#[test]
fn test_overlaps_contained() {
let mut set = IntervalSet::new();
set.insert(10..20);
assert!(set.overlaps(12..18));
}
#[test]
fn test_overlaps_containing() {
let mut set = IntervalSet::new();
set.insert(10..20);
assert!(set.overlaps(5..25));
}
#[test]
fn test_covers_empty_range() {
let mut set = IntervalSet::new();
set.insert(10..20);
assert!(set.covers(15..15));
}
#[test]
fn test_covers_empty_set() {
let set: IntervalSet<u32> = IntervalSet::new();
assert!(!set.covers(0..10));
}
#[test]
fn test_covers_fully_covered() {
let mut set = IntervalSet::new();
set.insert(0..30);
assert!(set.covers(5..25));
assert!(set.covers(0..30));
}
#[test]
fn test_covers_contiguous() {
let mut set = IntervalSet::new();
set.insert(0..10);
set.insert(10..20);
set.insert(20..30);
assert!(set.covers(0..30));
assert!(set.covers(5..25));
}
#[test]
fn test_covers_with_gap() {
let mut set = IntervalSet::new();
set.insert(0..10);
set.insert(20..30);
assert!(!set.covers(0..30));
assert!(!set.covers(5..25));
}
#[test]
fn test_covers_partial() {
let mut set = IntervalSet::new();
set.insert(10..20);
assert!(!set.covers(0..15)); assert!(!set.covers(15..25)); }
#[test]
fn test_gaps_empty() {
let set: IntervalSet<u32> = IntervalSet::new();
let gaps: Vec<_> = set.gaps().collect();
assert!(gaps.is_empty());
}
#[test]
fn test_gaps_single_interval() {
let mut set = IntervalSet::new();
set.insert(10..20);
let gaps: Vec<_> = set.gaps().collect();
assert!(gaps.is_empty());
}
#[test]
fn test_gaps_adjacent() {
let mut set = IntervalSet::new();
set.insert(0..10);
set.insert(10..20);
let gaps: Vec<_> = set.gaps().collect();
assert!(gaps.is_empty());
}
#[test]
fn test_gaps_multiple() {
let mut set = IntervalSet::new();
set.insert(0..10);
set.insert(20..30);
set.insert(40..50);
let gaps: Vec<_> = set.gaps().collect();
assert_eq!(gaps, vec![10..20, 30..40]);
}
#[test]
fn test_iter_overlapping_empty() {
let set: IntervalSet<u32> = IntervalSet::new();
let overlapping: Vec<_> = set.iter_overlapping(0..100).collect();
assert!(overlapping.is_empty());
}
#[test]
fn test_iter_overlapping_none() {
let mut set = IntervalSet::new();
set.insert(0..10);
set.insert(20..30);
let overlapping: Vec<_> = set.iter_overlapping(12..18).collect();
assert!(overlapping.is_empty());
}
#[test]
fn test_iter_overlapping_some() {
let mut set = IntervalSet::new();
set.insert(0..10);
set.insert(20..30);
set.insert(40..50);
let overlapping: Vec<_> = set.iter_overlapping(15..45).collect();
assert_eq!(overlapping, vec![20..30, 40..50]);
}
#[test]
fn test_iter_overlapping_all() {
let mut set = IntervalSet::new();
set.insert(0..10);
set.insert(20..30);
let overlapping: Vec<_> = set.iter_overlapping(0..100).collect();
assert_eq!(overlapping, vec![0..10, 20..30]);
}
#[test]
fn test_retain_all() {
let mut set = IntervalSet::new();
set.insert(0..10);
set.insert(20..30);
set.retain(|_| true);
assert_eq!(set.len(), 2);
}
#[test]
fn test_retain_none() {
let mut set = IntervalSet::new();
set.insert(0..10);
set.insert(20..30);
set.retain(|_| false);
assert!(set.is_empty());
}
#[test]
fn test_retain_some() {
let mut set = IntervalSet::new();
set.insert(0..10);
set.insert(20..30);
set.insert(40..50);
set.retain(|r| r.start >= 20);
let intervals: Vec<_> = set.iter().collect();
assert_eq!(intervals, vec![20..30, 40..50]);
}
#[test]
fn test_split_at_empty() {
let mut set: IntervalSet<u32> = IntervalSet::new();
set.split_at(10);
assert!(set.is_empty());
}
#[test]
fn test_split_at_outside() {
let mut set = IntervalSet::new();
set.insert(10..20);
set.split_at(5);
set.split_at(25);
let intervals: Vec<_> = set.iter().collect();
assert_eq!(intervals, vec![10..20]);
}
#[test]
fn test_split_at_boundary() {
let mut set = IntervalSet::new();
set.insert(10..20);
set.split_at(10);
set.split_at(20);
let intervals: Vec<_> = set.iter().collect();
assert_eq!(intervals, vec![10..20]);
}
#[test]
fn test_split_at_middle() {
let mut set = IntervalSet::new();
set.insert(0..20);
set.split_at(10);
let intervals: Vec<_> = set.iter().collect();
assert_eq!(intervals, vec![0..10, 10..20]);
}
#[test]
fn test_split_at_multiple() {
let mut set = IntervalSet::new();
set.insert(0..30);
set.split_at(10);
set.split_at(20);
let intervals: Vec<_> = set.iter().collect();
assert_eq!(intervals, vec![0..10, 10..20, 20..30]);
}
#[test]
fn test_first_last_after_modifications() {
let mut set = IntervalSet::new();
set.insert(10..20);
assert_eq!(set.first(), Some(10..20));
assert_eq!(set.last(), Some(10..20));
set.insert(0..5);
assert_eq!(set.first(), Some(0..5));
assert_eq!(set.last(), Some(10..20));
set.insert(30..40);
assert_eq!(set.first(), Some(0..5));
assert_eq!(set.last(), Some(30..40));
set.remove(0..5);
assert_eq!(set.first(), Some(10..20));
set.remove(30..40);
assert_eq!(set.last(), Some(10..20));
}
#[test]
fn test_first_last_single_point_interval() {
let mut set = IntervalSet::new();
set.insert(5..6); assert_eq!(set.first(), Some(5..6));
assert_eq!(set.last(), Some(5..6));
}
#[test]
fn test_span_single_point() {
let mut set = IntervalSet::new();
set.insert(5..6);
assert_eq!(set.span(), Some(5..6));
}
#[test]
fn test_span_after_split() {
let mut set = IntervalSet::new();
set.insert(0..100);
let span_before = set.span();
set.split_at(50);
let span_after = set.span();
assert_eq!(span_before, span_after);
assert_eq!(span_after, Some(0..100));
}
#[test]
fn test_span_with_gaps() {
let mut set = IntervalSet::new();
set.insert(0..10);
set.insert(90..100);
assert_eq!(set.span(), Some(0..100));
}
#[test]
fn test_overlaps_empty_query() {
let mut set = IntervalSet::new();
set.insert(10..20);
assert!(!set.overlaps(15..15));
}
#[test]
fn test_overlaps_single_point_query() {
let mut set = IntervalSet::new();
set.insert(10..20);
assert!(set.overlaps(15..16));
assert!(set.overlaps(10..11));
assert!(!set.overlaps(20..21));
}
#[test]
fn test_overlaps_exact_match() {
let mut set = IntervalSet::new();
set.insert(10..20);
assert!(set.overlaps(10..20));
}
#[test]
fn test_overlaps_touching_boundaries() {
let mut set = IntervalSet::new();
set.insert(10..20);
set.insert(30..40);
assert!(!set.overlaps(20..30));
assert!(set.overlaps(19..30));
assert!(set.overlaps(20..31));
}
#[test]
fn test_covers_single_point() {
let mut set = IntervalSet::new();
set.insert(10..20);
assert!(set.covers(15..16));
assert!(set.covers(10..11));
assert!(set.covers(19..20));
}
#[test]
fn test_covers_exact_boundaries() {
let mut set = IntervalSet::new();
set.insert(10..20);
assert!(set.covers(10..20));
assert!(set.covers(10..15));
assert!(set.covers(15..20));
}
#[test]
fn test_covers_after_split() {
let mut set = IntervalSet::new();
set.insert(0..100);
assert!(set.covers(25..75));
set.split_at(50);
assert!(set.covers(25..75));
}
#[test]
fn test_covers_barely_not_covered() {
let mut set = IntervalSet::new();
set.insert(10..20);
assert!(!set.covers(10..21));
assert!(!set.covers(9..20));
}
#[test]
fn test_gaps_two_intervals_no_gap() {
let mut set = IntervalSet::new();
set.insert(0..10);
set.insert(10..20); let gaps: Vec<_> = set.gaps().collect();
assert!(gaps.is_empty());
assert_eq!(set.len(), 1); }
#[test]
fn test_gaps_single_point_intervals() {
let mut set = IntervalSet::new();
set.insert(0..1);
set.insert(5..6);
set.insert(10..11);
let gaps: Vec<_> = set.gaps().collect();
assert_eq!(gaps, vec![1..5, 6..10]);
}
#[test]
fn test_gaps_large_gap() {
let mut set: IntervalSet<u32> = IntervalSet::new();
set.insert(0..10);
set.insert(1000000..1000010);
let gaps: Vec<_> = set.gaps().collect();
assert_eq!(gaps, vec![10..1000000]);
}
#[test]
fn test_iter_overlapping_exact_match() {
let mut set = IntervalSet::new();
set.insert(0..10);
set.insert(20..30);
set.insert(40..50);
let overlapping: Vec<_> = set.iter_overlapping(20..30).collect();
assert_eq!(overlapping, vec![20..30]);
}
#[test]
fn test_iter_overlapping_empty_query() {
let mut set = IntervalSet::new();
set.insert(0..100);
let overlapping: Vec<_> = set.iter_overlapping(50..50).collect();
assert!(overlapping.is_empty());
}
#[test]
fn test_iter_overlapping_partial_overlap() {
let mut set = IntervalSet::new();
set.insert(10..20);
let overlapping: Vec<_> = set.iter_overlapping(15..25).collect();
assert_eq!(overlapping, vec![10..20]);
let overlapping: Vec<_> = set.iter_overlapping(5..15).collect();
assert_eq!(overlapping, vec![10..20]);
}
#[test]
fn test_iter_overlapping_between_intervals() {
let mut set = IntervalSet::new();
set.insert(0..10);
set.insert(20..30);
let overlapping: Vec<_> = set.iter_overlapping(12..18).collect();
assert!(overlapping.is_empty());
}
#[test]
fn test_retain_by_length() {
let mut set = IntervalSet::new();
set.insert(0..5); set.insert(10..30); set.insert(40..45); set.retain(|r| r.end - r.start > 10);
let intervals: Vec<_> = set.iter().collect();
assert_eq!(intervals, vec![10..30]);
}
#[test]
fn test_retain_then_operations() {
let mut set = IntervalSet::new();
set.insert(0..10);
set.insert(20..30);
set.insert(40..50);
set.retain(|r| r.start >= 20);
assert_eq!(set.first(), Some(20..30));
assert_eq!(set.last(), Some(40..50));
assert_eq!(set.span(), Some(20..50));
assert!(set.overlaps(25..45));
assert!(set.covers(22..28));
}
#[test]
fn test_retain_empty_result() {
let mut set = IntervalSet::new();
set.insert(0..10);
set.retain(|r| r.start > 100);
assert!(set.is_empty());
assert_eq!(set.first(), None);
assert_eq!(set.span(), None);
}
#[test]
fn test_split_at_same_point_twice() {
let mut set = IntervalSet::new();
set.insert(0..30);
set.split_at(15);
set.split_at(15); let intervals: Vec<_> = set.iter().collect();
assert_eq!(intervals, vec![0..15, 15..30]);
}
#[test]
fn test_split_at_multiple_intervals() {
let mut set = IntervalSet::new();
set.insert(0..20);
set.insert(30..50);
set.split_at(10);
let intervals: Vec<_> = set.iter().collect();
assert_eq!(intervals, vec![0..10, 10..20, 30..50]);
}
#[test]
fn test_split_at_in_gap() {
let mut set = IntervalSet::new();
set.insert(0..10);
set.insert(20..30);
set.split_at(15);
let intervals: Vec<_> = set.iter().collect();
assert_eq!(intervals, vec![0..10, 20..30]);
}
#[test]
fn test_split_preserves_coverage() {
let mut set = IntervalSet::new();
set.insert(0..100);
assert!(set.covers(0..100));
set.split_at(25);
set.split_at(50);
set.split_at(75);
assert!(set.covers(0..100));
assert!(set.contains(0));
assert!(set.contains(25));
assert!(set.contains(50));
assert!(set.contains(75));
assert!(set.contains(99));
}
#[test]
fn test_gaps_after_retain() {
let mut set = IntervalSet::new();
set.insert(0..10);
set.insert(20..30);
set.insert(40..50);
set.retain(|r| r.start != 20); let gaps: Vec<_> = set.gaps().collect();
assert_eq!(gaps, vec![10..40]); }
#[test]
fn test_overlaps_after_split() {
let mut set = IntervalSet::new();
set.insert(0..100);
set.split_at(50);
assert!(set.overlaps(25..75));
assert!(set.overlaps(0..1));
assert!(set.overlaps(99..100));
}
#[test]
fn test_iter_overlapping_after_split() {
let mut set = IntervalSet::new();
set.insert(0..100);
set.split_at(50);
let overlapping: Vec<_> = set.iter_overlapping(25..75).collect();
assert_eq!(overlapping, vec![0..50, 50..100]);
}
#[test]
fn test_utility_methods_near_max() {
let mut set: IntervalSet<u32> = IntervalSet::new();
let max = u32::MAX;
set.insert((max - 100)..(max - 50));
set.insert((max - 30)..(max - 10));
assert_eq!(set.first(), Some((max - 100)..(max - 50)));
assert_eq!(set.last(), Some((max - 30)..(max - 10)));
assert_eq!(set.span(), Some((max - 100)..(max - 10)));
assert!(set.overlaps((max - 80)..(max - 60)));
assert!(!set.covers((max - 100)..(max - 10))); }
#[test]
fn test_utility_methods_near_min_signed() {
let mut set: IntervalSet<i32> = IntervalSet::new();
let min = i32::MIN;
set.insert(min..(min + 50));
set.insert((min + 100)..(min + 150));
assert_eq!(set.first(), Some(min..(min + 50)));
assert_eq!(set.last(), Some((min + 100)..(min + 150)));
assert_eq!(set.span(), Some(min..(min + 150)));
let gaps: Vec<_> = set.gaps().collect();
assert_eq!(gaps, vec![(min + 50)..(min + 100)]);
}
#[test]
fn test_utility_methods_crossing_zero() {
let mut set: IntervalSet<i32> = IntervalSet::new();
set.insert(-50..50);
assert_eq!(set.span(), Some(-50..50));
assert!(set.contains(-25));
assert!(set.contains(0));
assert!(set.contains(25));
assert!(set.covers(-25..25));
set.split_at(0);
let intervals: Vec<_> = set.iter().collect();
assert_eq!(intervals, vec![-50..0, 0..50]);
}
}