use core::{
ops::{Range, RangeInclusive, RangeBounds, RangeFull, AddAssign, Sub},
fmt::{self, Debug, Formatter},
iter::{FromIterator, IntoIterator},
};
#[cfg(feature = "dot")]
use std::io::{self, Write};
#[cfg(feature = "serde")]
use serde::{Serialize, Serializer, Deserialize, Deserializer};
use super::{
IntervalMap,
ix::{IndexType, DefaultIx},
iter::*,
};
#[derive(Clone)]
pub struct IntervalSet<T, Ix: IndexType = DefaultIx> {
inner: IntervalMap<T, (), Ix>,
}
impl<T: PartialOrd + Copy> IntervalSet<T> {
pub fn new() -> Self {
Self::default()
}
}
impl<T: PartialOrd + Copy, Ix: IndexType> Default for IntervalSet<T, Ix> {
fn default() -> Self {
Self {
inner: IntervalMap::default(),
}
}
}
impl<T: PartialOrd + Copy, Ix: IndexType> IntervalSet<T, Ix> {
pub fn with_capacity(capacity: usize) -> Self {
Self {
inner: IntervalMap::with_capacity(capacity),
}
}
pub fn from_sorted(iter: impl IntoIterator<Item = Range<T>>) -> Self {
Self {
inner: IntervalMap::from_sorted(iter.into_iter().map(|range| (range, ()))),
}
}
#[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 shrink_to_fit(&mut self) {
self.inner.shrink_to_fit()
}
pub fn insert(&mut self, interval: Range<T>) -> bool {
self.inner.insert(interval, ()).is_none()
}
pub fn contains(&self, interval: Range<T>) -> bool {
self.inner.contains(interval)
}
pub fn remove(&mut self, interval: Range<T>) -> bool {
self.inner.remove(interval).is_some()
}
#[inline]
pub fn range(&self) -> Option<Range<T>> {
self.inner.range()
}
pub fn smallest(&self) -> Option<Range<T>> {
self.inner.smallest().map(|(interval, _)| interval)
}
pub fn remove_smallest(&mut self) -> Option<Range<T>> {
self.inner.remove_smallest().map(|(interval, _)| interval)
}
pub fn largest(&self) -> Option<Range<T>> {
self.inner.largest().map(|(interval, _)| interval)
}
pub fn remove_largest(&mut self) -> Option<Range<T>> {
self.inner.remove_largest().map(|(interval, _)| interval)
}
#[inline]
pub fn has_overlap(&self, query: impl RangeBounds<T>) -> bool {
self.inner.has_overlap(query)
}
pub fn iter<R>(&self, query: R) -> Intervals<'_, T, (), R, Ix>
where R: RangeBounds<T>,
{
self.inner.intervals(query)
}
pub fn overlap(&self, point: T) -> Intervals<'_, T, (), RangeInclusive<T>, Ix> {
self.inner.intervals(point..=point)
}
pub fn into_iter<R>(self, query: R) -> IntoIntervals<T, (), R, Ix>
where R: RangeBounds<T>,
{
IntoIntervals::new(self.inner, query)
}
pub fn unsorted_iter(&self) -> UnsIntervals<'_, T, (), Ix> {
UnsIntervals::new(&self.inner)
}
pub fn unsorted_into_iter(self) -> UnsIntoIntervals<T, (), Ix> {
UnsIntoIntervals::new(self.inner)
}
}
impl<T: PartialOrd + Copy, Ix: IndexType> IntoIterator for IntervalSet<T, Ix> {
type IntoIter = IntoIntervals<T, (), RangeFull, Ix>;
type Item = Range<T>;
fn into_iter(self) -> Self::IntoIter {
IntoIntervals::new(self.inner, ..)
}
}
impl<T: PartialOrd + Copy> FromIterator<Range<T>> for IntervalSet<T> {
fn from_iter<I: IntoIterator<Item = Range<T>>>(iter: I) -> Self {
let mut set = IntervalSet::new();
for range in iter {
set.insert(range);
}
set
}
}
impl<T, Ix> IntervalSet<T, Ix>
where T: PartialOrd + Copy + Default + AddAssign + Sub<Output = T>,
Ix: IndexType,
{
#[inline]
pub fn covered_len(&self, query: impl RangeBounds<T>) -> T {
self.inner.covered_len(query)
}
}
#[cfg(feature = "dot")]
impl<T: PartialOrd + Copy + core::fmt::Display, Ix: IndexType> IntervalSet<T, Ix> {
pub fn write_dot(&self, writer: impl Write) -> io::Result<()> {
self.inner.write_dot_without_values(writer)
}
}
impl<T: PartialOrd + Copy + Debug, Ix: IndexType> Debug for IntervalSet<T, Ix> {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
write!(f, "{{")?;
let mut need_comma = false;
for interval in self.iter(..) {
if need_comma {
write!(f, ", ")?;
} else {
need_comma = true;
}
write!(f, "{:?}", interval)?;
}
write!(f, "}}")
}
}
#[cfg(feature = "serde")]
impl<T, Ix> Serialize for IntervalSet<T, Ix>
where
T: PartialOrd + Copy + Serialize,
Ix: IndexType + Serialize,
{
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
self.inner.serialize(serializer)
}
}
#[cfg(feature = "serde")]
impl<'de, T, Ix> Deserialize<'de> for IntervalSet<T, Ix>
where
T: PartialOrd + Copy + Deserialize<'de>,
Ix: IndexType + Deserialize<'de>,
{
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
let inner = <IntervalMap<T, (), Ix>>::deserialize(deserializer)?;
Ok(IntervalSet { inner })
}
}