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::BitAnd;
pub struct IntervalsAnd<Ia, Ib> {
i_a: Ia,
i_b: Ib,
}
impl<Ia, Ib> IntervalsAnd<Ia, Ib> {
pub fn new(i_a: Ia, i_b: Ib) -> Self {
Self { i_a, i_b }
}
}
impl<Ia, Ib, E> Intervals for IntervalsAnd<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 = (Ia::Value, Ib::Value);
fn head(&mut self, pos: Option<LeftT<Self::Endpoint>>) -> Option<Interval<E, Self::Value>> {
let mut ha = self.i_a.head(pos.clone())?;
let mut pos = match pos {
None => ha.left(),
Some(p) => ha.left().max(p),
};
let mut hb = self.i_b.head(Some(pos.clone()))?;
pos = hb.left().max(pos.clone());
loop {
let mut ok = true;
if pos >= ha.right().into_left() {
ok = false;
pos = hb.left().max(pos);
ha = self.i_a.head(Some(pos.clone()))?;
}
if pos >= hb.right().into_left() {
ok = false;
pos = ha.left().max(pos);
hb = self.i_b.head(Some(pos.clone()))?;
}
if ok {
break;
}
}
let e1 = ha.left().max(hb.left());
let e2 = ha.right().min(hb.right());
Some(Interval::new_lr(e1, e2, (ha.value(), hb.value())))
}
}
pub fn and<Ia, Ib>(a: Ia, b: Ib) -> IntervalsWrap<IntervalsAnd<Ia, Ib>> {
let iand = IntervalsAnd::new(a, b);
IntervalsWrap::new(iand)
}
pub fn and_cached<Ia, Ib>(a: Ia, b: Ib) -> IntervalsCache<IntervalsAnd<Ia, Ib>>
where
IntervalsAnd<Ia, Ib>: Intervals,
{
let io = IntervalsAnd::new(a, b);
IntervalsCache::new(io)
}
#[cfg(feature = "operators")]
impl<I, Rhs> BitAnd<Rhs> for IntervalsWrap<I>
where
IntervalsAnd<Self, Rhs>: Intervals,
I: Intervals,
Rhs: Intervals,
{
type Output = IntervalsWrap<IntervalsAnd<Self, Rhs>>;
fn bitand(self, c: Rhs) -> Self::Output {
and(self, c)
}
}
#[cfg(feature = "operators")]
impl<T, V, Ic> BitAnd<Ic> for IntervalsSingle<T, V>
where
Self: Intervals,
Ic: Intervals<Endpoint = <Self as Intervals>::Endpoint>,
{
type Output = IntervalsWrap<IntervalsAnd<Self, Ic>>;
fn bitand(self, c: Ic) -> Self::Output {
and(self, c)
}
}
#[cfg(feature = "operators")]
impl<'a, E, V, Rhs> BitAnd<Rhs> for IntervalsFromArray<'a, E, V>
where
Self: Intervals,
Rhs: Intervals<Endpoint = <Self as Intervals>::Endpoint>,
{
type Output = IntervalsWrap<IntervalsAnd<Self, Rhs>>;
fn bitand(self, c: Rhs) -> Self::Output {
and(self, c)
}
}
#[cfg(feature = "operators")]
impl<It, V, Ic> BitAnd<Ic> for IntervalsMap<It, V>
where
Self: Intervals,
Ic: Intervals<Endpoint = <Self as Intervals>::Endpoint>,
{
type Output = IntervalsWrap<IntervalsAnd<Self, Ic>>;
fn bitand(self, c: Ic) -> Self::Output {
and(self, c)
}
}
#[cfg(feature = "operators")]
impl<It, F, G, Tin, Tout, Ic> BitAnd<Ic> for IntervalsEndpointMap<It, F, G, Tin, Tout>
where
Self: Intervals,
Ic: Intervals<Endpoint = <Self as Intervals>::Endpoint>,
{
type Output = IntervalsWrap<IntervalsAnd<Self, Ic>>;
fn bitand(self, c: Ic) -> Self::Output {
and(self, c)
}
}