use core::{iter::FusedIterator, ops::RangeInclusive};
use crate::{Integer, SortedDisjoint};
#[derive(Clone, Debug)]
#[must_use = "iterators are lazy and do nothing unless consumed"]
pub struct NotIter<T, I> {
iter: I,
start_not: T,
next_time_return_none: bool,
}
impl<T, I> NotIter<T, I>
where
T: Integer,
I: SortedDisjoint<T>,
{
#[inline]
pub(crate) fn new<J>(iter: J) -> Self
where
J: IntoIterator<Item = RangeInclusive<T>, IntoIter = I>,
{
Self {
iter: iter.into_iter(),
start_not: T::min_value(),
next_time_return_none: false,
}
}
}
impl<T, I> FusedIterator for NotIter<T, I>
where
T: Integer,
I: SortedDisjoint<T> + FusedIterator,
{
}
impl<T, I> Iterator for NotIter<T, I>
where
T: Integer,
I: SortedDisjoint<T>,
{
type Item = RangeInclusive<T>;
fn next(&mut self) -> Option<RangeInclusive<T>> {
debug_assert!(T::min_value() <= T::max_value()); if self.next_time_return_none {
return None;
}
let next_item = self.iter.next();
if let Some(range) = next_item {
let (start, end) = range.into_inner();
debug_assert!(start <= end);
if self.start_not < start {
let result = Some(self.start_not..=start.sub_one());
if end < T::max_value() {
self.start_not = end.add_one();
} else {
self.next_time_return_none = true;
}
result
} else if end < T::max_value() {
self.start_not = end.add_one();
self.next() } else {
self.next_time_return_none = true;
None
}
} else {
self.next_time_return_none = true;
Some(self.start_not..=T::max_value())
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
let (low, high) = self.iter.size_hint();
let low = low.saturating_sub(1);
let high = high.map(|high| high.saturating_add(1));
(low, high)
}
}