use std::iter::FusedIterator;
use crate::intervals::absolute::AbsBoundPair;
use crate::intervals::relative::RelBoundPair;
use crate::iter::intervals::layered_bounds::{
LayeredBoundsState,
LayeredBoundsStateChangeAtAbsBound,
LayeredBoundsStateChangeAtRelBound,
};
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct LayeredAbsBoundsIntersection<I> {
iter: I,
exhausted: bool,
}
impl<I> LayeredAbsBoundsIntersection<I>
where
I: Iterator<Item = LayeredBoundsStateChangeAtAbsBound>,
{
pub fn new(iter: I) -> LayeredAbsBoundsIntersection<I> {
LayeredAbsBoundsIntersection {
iter,
exhausted: false,
}
}
}
impl<I> Iterator for LayeredAbsBoundsIntersection<I>
where
I: Iterator<Item = LayeredBoundsStateChangeAtAbsBound>,
{
type Item = AbsBoundPair;
fn next(&mut self) -> Option<Self::Item> {
if self.exhausted {
return None;
}
loop {
let Some(current) = self.iter.next() else {
self.exhausted = true;
return None;
};
if !matches!(current.new_state(), LayeredBoundsState::BothLayers) {
continue;
}
let Some(start) = current.new_state_start() else {
unreachable!("When the state is not `NoLayers`, the new state's start is guaranteed to exist");
};
let Some(next) = self.iter.next() else {
unreachable!(
"The input requirements guarantee that the given iterator cannot end on an active state such as \
`BothLayers`"
);
};
let Some(end) = next.old_state_end() else {
unreachable!(
"We can infer the guarantee that the state change following one that transitions to `BothLayers` \
must contain an end to the old state, given that the input requirements guarantee that the given \
iterator cannot end on an active state such as `BothLayers`"
);
};
return Some(AbsBoundPair::new(start, end));
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
(0, self.iter.size_hint().1.map(|upper_bound| upper_bound.div_ceil(2)))
}
}
impl<I> FusedIterator for LayeredAbsBoundsIntersection<I> where I: Iterator<Item = LayeredBoundsStateChangeAtAbsBound> {}
pub trait LayeredAbsBoundsIntersectionIteratorDispatcher
where
Self: IntoIterator<Item = LayeredBoundsStateChangeAtAbsBound> + Sized,
{
fn abs_intersect_layered(self) -> LayeredAbsBoundsIntersection<Self::IntoIter> {
LayeredAbsBoundsIntersection::new(self.into_iter())
}
}
impl<I> LayeredAbsBoundsIntersectionIteratorDispatcher for I where
I: IntoIterator<Item = LayeredBoundsStateChangeAtAbsBound> + Sized
{
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct LayeredRelBoundsIntersection<I> {
iter: I,
exhausted: bool,
}
impl<I> LayeredRelBoundsIntersection<I>
where
I: Iterator<Item = LayeredBoundsStateChangeAtRelBound>,
{
pub fn new(iter: I) -> LayeredRelBoundsIntersection<I> {
LayeredRelBoundsIntersection {
iter,
exhausted: false,
}
}
}
impl<I> Iterator for LayeredRelBoundsIntersection<I>
where
I: Iterator<Item = LayeredBoundsStateChangeAtRelBound>,
{
type Item = RelBoundPair;
fn next(&mut self) -> Option<Self::Item> {
if self.exhausted {
return None;
}
loop {
let Some(current) = self.iter.next() else {
self.exhausted = true;
return None;
};
if !matches!(current.new_state(), LayeredBoundsState::BothLayers) {
continue;
}
let Some(start) = current.new_state_start() else {
unreachable!("When the state is not `NoLayers`, the new state's start is guaranteed to exist");
};
let Some(next) = self.iter.next() else {
unreachable!(
"The input requirements guarantee that the given iterator cannot end on an active state such as \
`BothLayers`"
);
};
let Some(end) = next.old_state_end() else {
unreachable!(
"We can infer the guarantee that the state change following one that transitions to `BothLayers` \
must contain an end to the old state, given that the input requirements guarantee that the given \
iterator cannot end on an active state such as `BothLayers`"
);
};
return Some(RelBoundPair::new(start, end));
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
(0, self.iter.size_hint().1.map(|upper_bound| upper_bound.div_ceil(2)))
}
}
impl<I> FusedIterator for LayeredRelBoundsIntersection<I> where I: Iterator<Item = LayeredBoundsStateChangeAtRelBound> {}
pub trait LayeredRelBoundsIntersectionIteratorDispatcher
where
Self: IntoIterator<Item = LayeredBoundsStateChangeAtRelBound> + Sized,
{
fn rel_intersect_layered(self) -> LayeredRelBoundsIntersection<Self::IntoIter> {
LayeredRelBoundsIntersection::new(self.into_iter())
}
}
impl<I> LayeredRelBoundsIntersectionIteratorDispatcher for I where
I: IntoIterator<Item = LayeredBoundsStateChangeAtRelBound> + Sized
{
}