usesuper::plumbing::*; usesuper::*; use std::iter::Fuse;
/// `Interleave` is an iterator that interleaves elements of iterators /// `i` and `j` in one continuous iterator. This struct is created by /// the [`interleave()`] method on [`IndexedParallelIterator`] /// /// [`interleave()`]: trait.IndexedParallelIterator.html#method.interleave /// [`IndexedParallelIterator`]: trait.IndexedParallelIterator.html #[must_use = "iterator adaptors are lazy and do nothing unless consumed"] #[derive(Debug, Clone)] pubstruct Interleave<I, J> where
I: IndexedParallelIterator,
J: IndexedParallelIterator<Item = I::Item>,
{
i: I,
j: J,
}
impl<I, J> Interleave<I, J> where
I: IndexedParallelIterator,
J: IndexedParallelIterator<Item = I::Item>,
{ /// Creates a new `Interleave` iterator pub(super) fn new(i: I, j: J) -> Self {
Interleave { i, j }
}
}
impl<I, J> ParallelIterator for Interleave<I, J> where
I: IndexedParallelIterator,
J: IndexedParallelIterator<Item = I::Item>,
{ type Item = I::Item;
fn drive_unindexed<C>(self, consumer: C) -> C::Result where
C: Consumer<I::Item>,
{
bridge(self, consumer)
}
/// We know 0 < index <= self.i_len + self.j_len /// /// Find a, b satisfying: /// /// (1) 0 < a <= self.i_len /// (2) 0 < b <= self.j_len /// (3) a + b == index /// /// For even splits, set a = b = index/2. /// For odd splits, set a = (index/2)+1, b = index/2, if `i` /// should yield the next element, otherwise, if `j` should yield /// the next element, set a = index/2 and b = (index/2)+1 fn split_at(self, index: usize) -> (Self, Self) { #[inline] fn odd_offset(flag: bool) -> usize {
(!flag) as usize
}
/// Wrapper for Interleave to implement DoubleEndedIterator and /// ExactSizeIterator. /// /// This iterator is fused. struct InterleaveSeq<I, J> {
i: Fuse<I>,
j: Fuse<J>,
/// Flag to control which iterator should provide the next element. When /// `false` then `i` produces the next element, otherwise `j` produces the /// next element.
i_next: bool,
}
/// Iterator implementation for InterleaveSeq. This implementation is /// taken more or less verbatim from itertools. It is replicated here /// (instead of calling itertools directly), because we also need to /// implement `DoubledEndedIterator` and `ExactSizeIterator`. impl<I, J> Iterator for InterleaveSeq<I, J> where
I: Iterator,
J: Iterator<Item = I::Item>,
{ type Item = I::Item;
fn size_hint(&self) -> (usize, Option<usize>) { let (ih, jh) = (self.i.size_hint(), self.j.size_hint()); let min = ih.0.saturating_add(jh.0); let max = match (ih.1, jh.1) {
(Some(x), Some(y)) => x.checked_add(y),
_ => None,
};
(min, max)
}
}
// The implementation for DoubleEndedIterator requires // ExactSizeIterator to provide `next_back()`. The last element will // come from the iterator that runs out last (ie has the most elements // in it). If the iterators have the same number of elements, then the // last iterator will provide the last element. impl<I, J> DoubleEndedIterator for InterleaveSeq<I, J> where
I: DoubleEndedIterator + ExactSizeIterator,
J: DoubleEndedIterator<Item = I::Item> + ExactSizeIterator<Item = I::Item>,
{ #[inline] fn next_back(&mutself) -> Option<I::Item> { matchself.i.len().cmp(&self.j.len()) {
Ordering::Less => self.j.next_back(),
Ordering::Equal => { ifself.i_next { self.i.next_back()
} else { self.j.next_back()
}
}
Ordering::Greater => self.i.next_back(),
}
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.