use crate::bound::Bound;
use crate::interval::Interval;
use crate::normalize::Finite;
use crate::normalize::Normalize;
use crate::raw_interval::RawInterval;
use crate::tine_tree::TineTree;
#[cfg(feature="serde")] use serde::Deserialize;
#[cfg(feature="serde")] use serde::Serialize;
use std::iter::FromIterator;
use std::iter::FusedIterator;
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
#[repr(transparent)]
#[cfg_attr(feature="serde", derive(Deserialize, Serialize))]
#[cfg_attr(feature="serde", serde(transparent))]
#[cfg_attr(feature="serde",
serde(bound="for<'a> T: Ord + Serialize + Deserialize<'a> + Clone + 'a"))]
pub struct Selection<T>(TineTree<T>);
impl<T> Default for Selection<T>
where
T: Ord + Clone,
RawInterval<T>: Normalize,
{
fn default() -> Self {
Self::new()
}
}
impl<T> Selection<T>
where
T: Ord + Clone,
RawInterval<T>: Normalize
{
#[inline]
#[must_use]
pub fn new() -> Self {
Self(TineTree::new())
}
#[inline]
#[must_use]
pub fn empty() -> Self {
Self::new()
}
#[inline]
#[must_use]
pub fn full() -> Self {
Interval::full().into()
}
#[inline]
#[must_use]
pub fn lower_bound(&self) -> Option<Bound<T>> {
self.interval_iter().next().and_then(|i| i.lower_bound())
}
#[inline]
#[must_use]
pub fn upper_bound(&self) -> Option<Bound<T>> {
self.interval_iter().next_back().and_then(|i| i.upper_bound())
}
#[inline]
#[must_use]
pub fn infimum(&self) -> Option<T> {
self.0.lower_bound().and_then(|b| b.as_ref().cloned())
}
#[inline]
#[must_use]
pub fn supremum(&self) -> Option<T> {
self.0.upper_bound().and_then(|b| b.as_ref().cloned())
}
#[inline]
#[must_use]
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
#[inline]
#[must_use]
pub fn is_full(&self) -> bool {
self.0.is_full()
}
#[inline]
#[must_use]
pub fn is_bounded(&self) -> bool {
self.lower_bound().is_some() || self.upper_bound().is_some()
}
#[inline]
#[must_use]
pub fn is_left_bounded(&self) -> bool {
!matches!(self.lower_bound(), Some(Bound::Infinite))
}
#[inline]
#[must_use]
pub fn is_right_bounded(&self) -> bool {
!matches!(self.upper_bound(), Some(Bound::Infinite))
}
#[inline]
#[must_use]
pub fn is_half_bounded(&self) -> bool {
let l = self.is_left_bounded();
let r = self.is_right_bounded();
(l && !r) || (!l && r)
}
#[inline]
#[must_use]
pub fn contains(&self, point: &T) -> bool {
self.0.contains(point)
}
#[must_use]
pub fn intersects(&self, other: &Self) -> bool {
!self.0.intersect(&other.0).is_empty()
}
#[must_use]
pub fn complement(&self) -> Self {
Self(self.0.complement())
}
#[must_use]
pub fn intersect(&self, other: &Self) -> Self {
Self(self.0.intersect(&other.0))
}
#[must_use]
pub fn union(&self, other: &Self) -> Self {
Self(self.0.union(&other.0))
}
#[must_use]
pub fn minus(&self, other: &Self) -> Self {
Self(self.0.minus(&other.0))
}
#[must_use]
pub fn enclose(&self) -> Interval<T> {
Interval(self.0.enclose().normalized())
}
#[must_use]
pub fn closure(&self) -> Interval<T> {
Interval(self.0.closure().normalized())
}
pub fn intersect_in_place(&mut self, interval: Interval<T>) {
self.0.intersect_in_place(&interval.0.denormalized());
}
pub fn union_in_place(&mut self, interval: Interval<T>) {
self.0.union_in_place(&interval.0.denormalized());
}
pub fn minus_in_place(&mut self, interval: Interval<T>) {
self.0.minus_in_place(&interval.0.denormalized());
}
#[must_use]
pub fn interval_iter(&self) -> IntervalIter<'_, T> {
IntervalIter(self.0.interval_iter())
}
#[must_use]
pub fn into_interval_iter(self) -> IntoIntervalIter<T> {
IntoIntervalIter(self.0.into_iter())
}
}
impl<T> Selection<T>
where T: Ord + Clone + Finite,
{
#[must_use]
pub fn iter(&self) -> Iter<'_, T> {
Iter {
intervals: self.0.interval_iter(),
current: Interval::empty().iter(),
}
}
}
impl<T> IntoIterator for Selection<T>
where T: Ord + Clone + Finite,
{
type Item = T;
type IntoIter = IntoIter<T>;
fn into_iter(self) -> Self::IntoIter {
IntoIter {
intervals: self.0.into_iter(),
current: Interval::empty().iter(),
}
}
}
impl<'a, T> IntoIterator for &'a Selection<T>
where T: Ord + Clone + Finite,
{
type Item = T;
type IntoIter = Iter<'a, T>;
fn into_iter(self) -> Self::IntoIter {
Iter {
intervals: self.0.interval_iter(),
current: Interval::empty().iter(),
}
}
}
impl<T> Extend<Interval<T>> for Selection<T>
where
T: Ord + Clone,
RawInterval<T>: Normalize,
{
fn extend<I>(&mut self, iter: I) where I: IntoIterator<Item=Interval<T>> {
for interval in iter {
let raw = interval.0.denormalized();
self.0.union_in_place(&raw);
}
}
}
impl<T> From<Interval<T>> for Selection<T>
where
T: Ord + Clone,
RawInterval<T>: Normalize,
{
fn from(interval: Interval<T>) -> Self {
let raw = interval.0.denormalized();
Self(TineTree::from_raw_interval(raw))
}
}
impl<T> FromIterator<Interval<T>> for Selection<T>
where
T: Ord + Clone,
RawInterval<T>: Normalize,
{
fn from_iter<I>(iter: I) -> Self where I: IntoIterator<Item=Interval<T>> {
let mut selection = Self::new();
for interval in iter {
let raw = interval.0.denormalized();
selection.0.union_in_place(&raw);
}
selection
}
}
impl<T> FromIterator<T> for Selection<T>
where
T: Ord + Clone,
RawInterval<T>: Normalize,
{
fn from_iter<I>(iter: I) -> Self where I: IntoIterator<Item=T> {
let mut selection = Self::new();
for item in iter {
let raw = Interval::point(item).0.denormalized();
selection.0.union_in_place(&raw);
}
selection
}
}
#[derive(Debug)]
pub struct IntoIntervalIter<T>(crate::tine_tree::IntoIter<T>);
impl<T> Iterator for IntoIntervalIter<T>
where
T: Ord + Clone,
RawInterval<T>: Normalize,
{
type Item = Interval<T>;
fn next(&mut self) -> Option<Self::Item> {
self.0
.next()
.map(Normalize::normalized)
.map(Interval::from)
}
}
impl<T> DoubleEndedIterator for IntoIntervalIter<T>
where
T: Ord + Clone,
RawInterval<T>: Normalize,
{
fn next_back(&mut self) -> Option<Self::Item> {
self.0
.next_back()
.map(Normalize::normalized)
.map(Interval::from)
}
}
impl<T> FusedIterator for IntoIntervalIter<T>
where
T: Ord + Clone,
RawInterval<T>: Normalize,
{}
#[derive(Debug)]
pub struct IntervalIter<'t, T>(crate::tine_tree::Iter<'t, T>)
where T: Ord + Clone;
impl<'t, T> Iterator for IntervalIter<'t, T>
where
T: Ord + Clone,
RawInterval<T>: Normalize,
{
type Item = Interval<T>;
fn next(&mut self) -> Option<Self::Item> {
self.0
.next()
.map(Normalize::normalized)
.map(Interval::from)
}
}
impl<'t, T> DoubleEndedIterator for IntervalIter<'t, T>
where
T: Ord + Clone,
RawInterval<T>: Normalize,
{
fn next_back(&mut self) -> Option<Self::Item> {
self.0
.next_back()
.map(Normalize::normalized)
.map(Interval::from)
}
}
impl<'t, T> FusedIterator for IntervalIter<'t, T>
where
T: Ord + Clone,
RawInterval<T>: Normalize,
{}
#[derive(Debug)]
pub struct IntoIter<T>
where T: Ord + Clone
{
intervals: crate::tine_tree::IntoIter<T>,
current: crate::interval::Iter<T>,
}
impl<T> Iterator for IntoIter<T>
where T: Ord + Clone + Finite,
{
type Item = T;
fn next(&mut self) -> Option<Self::Item> {
if let Some(next) = self.current.next() {
return Some(next);
}
self.current = match self.intervals
.next()
.map(Normalize::normalized)
.map(Interval::from)
{
Some(interval) => interval.iter(),
None => return None,
};
self.current.next()
}
}
impl<T> DoubleEndedIterator for IntoIter<T>
where T: Ord + Clone + Finite,
{
fn next_back(&mut self) -> Option<Self::Item> {
if let Some(next_back) = self.current.next_back() {
return Some(next_back);
}
self.current = match self.intervals
.next_back()
.map(Normalize::normalized)
.map(Interval::from)
{
Some(interval) => interval.iter(),
None => return None,
};
self.current.next_back()
}
}
impl<T> FusedIterator for IntoIter<T>
where T: Ord + Clone + Finite,
{}
#[derive(Debug)]
pub struct Iter<'t, T>
where T: Ord + Clone + Finite
{
intervals: crate::tine_tree::Iter<'t, T>,
current: crate::interval::Iter<T>,
}
impl<'t, T> Iterator for Iter<'t, T>
where T: Ord + Clone + Finite,
{
type Item = T;
fn next(&mut self) -> Option<Self::Item> {
if let Some(next) = self.current.next() {
return Some(next);
}
self.current = match self.intervals
.next()
.map(Normalize::normalized)
.map(Interval::from)
{
Some(interval) => interval.iter(),
None => return None,
};
self.current.next()
}
}
impl<'t, T> DoubleEndedIterator for Iter<'t, T>
where T: Ord + Clone + Finite,
{
fn next_back(&mut self) -> Option<Self::Item> {
if let Some(next_back) = self.current.next_back() {
return Some(next_back);
}
self.current = match self.intervals
.next_back()
.map(Normalize::normalized)
.map(Interval::from)
{
Some(interval) => interval.iter(),
None => return None,
};
self.current.next_back()
}
}
impl<'t, T> FusedIterator for Iter<'t, T>
where T: Ord + Clone + Finite,
{}