diff options
Diffstat (limited to 'vendor/rayon/src/iter/interleave.rs')
-rw-r--r-- | vendor/rayon/src/iter/interleave.rs | 336 |
1 files changed, 0 insertions, 336 deletions
diff --git a/vendor/rayon/src/iter/interleave.rs b/vendor/rayon/src/iter/interleave.rs deleted file mode 100644 index 3cacc49..0000000 --- a/vendor/rayon/src/iter/interleave.rs +++ /dev/null @@ -1,336 +0,0 @@ -use super::plumbing::*; -use super::*; -use std::cmp; -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)] -pub struct 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) - } - - fn opt_len(&self) -> Option<usize> { - Some(self.len()) - } -} - -impl<I, J> IndexedParallelIterator for Interleave<I, J> -where - I: IndexedParallelIterator, - J: IndexedParallelIterator<Item = I::Item>, -{ - fn drive<C>(self, consumer: C) -> C::Result - where - C: Consumer<Self::Item>, - { - bridge(self, consumer) - } - - fn len(&self) -> usize { - self.i.len().checked_add(self.j.len()).expect("overflow") - } - - fn with_producer<CB>(self, callback: CB) -> CB::Output - where - CB: ProducerCallback<Self::Item>, - { - let (i_len, j_len) = (self.i.len(), self.j.len()); - return self.i.with_producer(CallbackI { - callback, - i_len, - j_len, - i_next: false, - j: self.j, - }); - - struct CallbackI<CB, J> { - callback: CB, - i_len: usize, - j_len: usize, - i_next: bool, - j: J, - } - - impl<CB, J> ProducerCallback<J::Item> for CallbackI<CB, J> - where - J: IndexedParallelIterator, - CB: ProducerCallback<J::Item>, - { - type Output = CB::Output; - - fn callback<I>(self, i_producer: I) -> Self::Output - where - I: Producer<Item = J::Item>, - { - self.j.with_producer(CallbackJ { - i_producer, - i_len: self.i_len, - j_len: self.j_len, - i_next: self.i_next, - callback: self.callback, - }) - } - } - - struct CallbackJ<CB, I> { - callback: CB, - i_len: usize, - j_len: usize, - i_next: bool, - i_producer: I, - } - - impl<CB, I> ProducerCallback<I::Item> for CallbackJ<CB, I> - where - I: Producer, - CB: ProducerCallback<I::Item>, - { - type Output = CB::Output; - - fn callback<J>(self, j_producer: J) -> Self::Output - where - J: Producer<Item = I::Item>, - { - let producer = InterleaveProducer::new( - self.i_producer, - j_producer, - self.i_len, - self.j_len, - self.i_next, - ); - self.callback.callback(producer) - } - } - } -} - -struct InterleaveProducer<I, J> -where - I: Producer, - J: Producer<Item = I::Item>, -{ - i: I, - j: J, - i_len: usize, - j_len: usize, - i_next: bool, -} - -impl<I, J> InterleaveProducer<I, J> -where - I: Producer, - J: Producer<Item = I::Item>, -{ - fn new(i: I, j: J, i_len: usize, j_len: usize, i_next: bool) -> InterleaveProducer<I, J> { - InterleaveProducer { - i, - j, - i_len, - j_len, - i_next, - } - } -} - -impl<I, J> Producer for InterleaveProducer<I, J> -where - I: Producer, - J: Producer<Item = I::Item>, -{ - type Item = I::Item; - type IntoIter = InterleaveSeq<I::IntoIter, J::IntoIter>; - - fn into_iter(self) -> Self::IntoIter { - InterleaveSeq { - i: self.i.into_iter().fuse(), - j: self.j.into_iter().fuse(), - i_next: self.i_next, - } - } - - fn min_len(&self) -> usize { - cmp::max(self.i.min_len(), self.j.min_len()) - } - - fn max_len(&self) -> usize { - cmp::min(self.i.max_len(), self.j.max_len()) - } - - /// 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 - } - - let even = index % 2 == 0; - let idx = index >> 1; - - // desired split - let (i_idx, j_idx) = ( - idx + odd_offset(even || self.i_next), - idx + odd_offset(even || !self.i_next), - ); - - let (i_split, j_split) = if self.i_len >= i_idx && self.j_len >= j_idx { - (i_idx, j_idx) - } else if self.i_len >= i_idx { - // j too short - (index - self.j_len, self.j_len) - } else { - // i too short - (self.i_len, index - self.i_len) - }; - - let trailing_i_next = even == self.i_next; - let (i_left, i_right) = self.i.split_at(i_split); - let (j_left, j_right) = self.j.split_at(j_split); - - ( - InterleaveProducer::new(i_left, j_left, i_split, j_split, self.i_next), - InterleaveProducer::new( - i_right, - j_right, - self.i_len - i_split, - self.j_len - j_split, - trailing_i_next, - ), - ) - } -} - -/// 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; - - #[inline] - fn next(&mut self) -> Option<Self::Item> { - self.i_next = !self.i_next; - if self.i_next { - match self.i.next() { - None => self.j.next(), - r => r, - } - } else { - match self.j.next() { - None => self.i.next(), - r => r, - } - } - } - - 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(&mut self) -> Option<I::Item> { - match self.i.len().cmp(&self.j.len()) { - Ordering::Less => self.j.next_back(), - Ordering::Equal => { - if self.i_next { - self.i.next_back() - } else { - self.j.next_back() - } - } - Ordering::Greater => self.i.next_back(), - } - } -} - -impl<I, J> ExactSizeIterator for InterleaveSeq<I, J> -where - I: ExactSizeIterator, - J: ExactSizeIterator<Item = I::Item>, -{ - #[inline] - fn len(&self) -> usize { - self.i.len() + self.j.len() - } -} |