use zengine_macro::generate_zip;
generate_zip!(14);
#[doc(hidden)]
pub enum OptionalIterator<I: Iterator> {
NoneIterator,
SomeIterator(I),
}
impl<I: Iterator> Iterator for OptionalIterator<I> {
type Item = Option<I::Item>;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
match self {
Self::NoneIterator => Some(None),
Self::SomeIterator(iterator) => Some(iterator.next()),
}
}
}
pub struct QueryIterator<I: Iterator> {
current_iter: Option<I>,
iterators: Vec<I>,
}
impl<I: Iterator> QueryIterator<I> {
#[doc(hidden)]
pub fn new(mut iterators: Vec<I>) -> Self {
let current_iter = iterators.pop();
Self {
current_iter,
iterators,
}
}
}
impl<I: Iterator> Iterator for QueryIterator<I> {
type Item = I::Item;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
match self.current_iter {
Some(ref mut iter) => match iter.next() {
None => {
self.current_iter = self.iterators.pop();
if let Some(ref mut iter) = self.current_iter {
iter.next()
} else {
None
}
}
item => item,
},
None => None,
}
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
let mut min = 0;
let mut max = 0;
if let Some(current_iter) = &self.current_iter {
let (i_min, i_max) = current_iter.size_hint();
min += i_min;
max += i_max.unwrap();
}
for i in self.iterators.iter() {
let (i_min, i_max) = i.size_hint();
min += i_min;
max += i_max.unwrap();
}
(min, Some(max))
}
}