use core::cmp::Ordering;
use crate::interval::*;
use crate::intervals::*;
use crate::IntervalsCache;
#[cfg(feature = "operators")]
use crate::IntervalsEndpointMap;
#[cfg(feature = "operators")]
use crate::IntervalsFromArray;
#[cfg(feature = "operators")]
use crate::IntervalsMap;
#[cfg(feature = "operators")]
use crate::IntervalsSingle;
#[cfg(feature = "operators")]
use core::ops::BitOr;
pub struct IntervalsOr<Ia, Ib> {
i_a: Ia,
i_b: Ib,
}
impl<Ia, Ib> IntervalsOr<Ia, Ib> {
pub fn new(i_a: Ia, i_b: Ib) -> Self {
Self { i_a, i_b }
}
}
impl<Ia, Ib, E> Intervals for IntervalsOr<Ia, Ib>
where
Ia: Intervals<Endpoint = E>,
Ib: Intervals<Endpoint = E>,
E: Clone + EndpointToggle,
LeftT<E>: Ord,
RightT<E>: Ord,
Ia::Value: Copy,
Ib::Value: Copy,
{
type Endpoint = E;
type Value = (Option<Ia::Value>, Option<Ib::Value>);
fn head(&mut self, pos: Option<LeftT<Self::Endpoint>>) -> Option<Interval<E, Self::Value>> {
let i_a = self.i_a.head(pos.clone());
let i_b = self.i_b.head(pos.clone());
if i_a.is_none() {
return i_b.map(|v| {
let left = match pos {
None => v.left().clone(),
Some(p) => v.left().max(p),
};
Interval::new_lr(left, v.right(), (None, Some(v.value())))
});
}
if i_b.is_none() {
return i_a.map(|v| {
let left = match pos {
None => v.left().clone(),
Some(p) => v.left().max(p),
};
Interval::new_lr(left, v.right(), (Some(v.value()), None))
});
}
let a = i_a.unwrap();
let a1 = match pos.clone() {
Some(p) => a.left().max(p),
None => a.left(),
};
let b = i_b.unwrap();
let b1 = match pos {
Some(p) => b.left().max(p),
None => b.left(),
};
use Ordering::*;
let r = match a1.partial_cmp(&b1).unwrap() {
Less => {
let right = a.right().min(b1.into_right());
Interval::new_lr(a1, right, (Some(a.value()), None))
}
Greater => {
let right: RightT<E> = b.right().min(a1.into_right());
Interval::new_lr(b1, right, (None, Some(b.value())))
}
Equal => {
let c = a.right().min(b.right());
Interval::new_lr(a1, c, (Some(a.value()), Some(b.value())))
}
};
Some(r)
}
}
pub fn or<Ia, Ib>(a: Ia, b: Ib) -> IntervalsWrap<IntervalsOr<Ia, Ib>> {
let ior = IntervalsOr::new(a, b);
IntervalsWrap::new(ior)
}
pub fn or_cached<Ia, Ib>(a: Ia, b: Ib) -> IntervalsCache<IntervalsOr<Ia, Ib>>
where
IntervalsOr<Ia, Ib>: Intervals,
{
let io = IntervalsOr::new(a, b);
IntervalsCache::new(io)
}
#[cfg(feature = "operators")]
impl<I, Rhs> BitOr<Rhs> for IntervalsWrap<I>
where
IntervalsOr<Self, Rhs>: Intervals,
{
type Output = IntervalsWrap<IntervalsOr<Self, Rhs>>;
fn bitor(self, c: Rhs) -> Self::Output {
or(self, c)
}
}
#[cfg(feature = "operators")]
impl<T, V, Ic> BitOr<Ic> for IntervalsSingle<T, V> {
type Output = IntervalsWrap<IntervalsOr<Self, Ic>>;
fn bitor(self, c: Ic) -> Self::Output {
or(self, c)
}
}
#[cfg(feature = "operators")]
impl<'a, E, V, Rhs> BitOr<Rhs> for IntervalsFromArray<'a, E, V>
where
Self: Intervals,
Rhs: Intervals<Endpoint = <Self as Intervals>::Endpoint>,
{
type Output = IntervalsWrap<IntervalsOr<Self, Rhs>>;
fn bitor(self, c: Rhs) -> Self::Output {
or(self, c)
}
}
#[cfg(feature = "operators")]
impl<It, F, Ic> BitOr<Ic> for IntervalsMap<It, F> {
type Output = IntervalsWrap<IntervalsOr<Self, Ic>>;
fn bitor(self, c: Ic) -> Self::Output {
or(self, c)
}
}
#[cfg(feature = "operators")]
impl<It, F, G, Tin, Tout, Ic> BitOr<Ic> for IntervalsEndpointMap<It, F, G, Tin, Tout> {
type Output = IntervalsWrap<IntervalsOr<Self, Ic>>;
fn bitor(self, c: Ic) -> Self::Output {
or(self, c)
}
}
#[cfg(feature = "operators")]
impl<It, Rhs> BitOr<Rhs> for IntervalsCache<It>
where
It: Intervals,
IntervalsOr<Self, Rhs>: Intervals,
{
type Output = IntervalsCache<IntervalsOr<Self, Rhs>>;
fn bitor(self, c: Rhs) -> Self::Output {
or_cached(self, c)
}
}