usesuper::plumbing::*; usesuper::*; use std::cell::Cell; use std::iter::{self, Fuse};
/// `Intersperse` is an iterator that inserts a particular item between each /// item of the adapted iterator. This struct is created by the /// [`intersperse()`] method on [`ParallelIterator`] /// /// [`intersperse()`]: trait.ParallelIterator.html#method.intersperse /// [`ParallelIterator`]: trait.ParallelIterator.html #[must_use = "iterator adaptors are lazy and do nothing unless consumed"] #[derive(Clone, Debug)] pubstruct Intersperse<I> where
I: ParallelIterator,
I::Item: Clone,
{
base: I,
item: I::Item,
}
impl<I> Intersperse<I> where
I: ParallelIterator,
I::Item: Clone,
{ /// Creates a new `Intersperse` iterator pub(super) fn new(base: I, item: I::Item) -> Self {
Intersperse { base, item }
}
}
impl<I> ParallelIterator for Intersperse<I> where
I: ParallelIterator,
I::Item: Clone + Send,
{ type Item = I::Item;
fn drive_unindexed<C>(self, consumer: C) -> C::Result where
C: UnindexedConsumer<I::Item>,
{ let consumer1 = IntersperseConsumer::new(consumer, self.item); self.base.drive_unindexed(consumer1)
}
impl<P> Producer for IntersperseProducer<P> where
P: Producer,
P::Item: Clone + Send,
{ type Item = P::Item; type IntoIter = IntersperseIter<P::IntoIter>;
// If there's more than one item, then even lengths end the opposite // of how they started with respect to interspersed clones.
clone_last: self.len > 1 && ((self.len & 1 == 0) ^ self.clone_first),
}
}
// The left needs half of the items from the base producer, and the // other half will be our interspersed item. If we're not leading with // a cloned item, then we need to round up the base number of items, // otherwise round down. let base_index = (index + !self.clone_first as usize) / 2; let (left_base, right_base) = self.base.split_at(base_index);
let left = IntersperseProducer {
base: left_base,
item: self.item.clone(),
len: index,
clone_first: self.clone_first,
};
let right = IntersperseProducer {
base: right_base,
item: self.item,
len: self.len - index,
// If the index is odd, the right side toggles `clone_first`.
clone_first: (index & 1 == 1) ^ self.clone_first,
};
(left, right)
}
fn fold_with<F>(self, folder: F) -> F where
F: Folder<Self::Item>,
{ let folder1 = IntersperseFolder {
base: folder,
item: self.item,
clone_first: self.clone_first,
}; self.base.fold_with(folder1).base
}
}
impl<I> Iterator for IntersperseIter<I> where
I: DoubleEndedIterator + ExactSizeIterator,
I::Item: Clone,
{ type Item = I::Item;
fn next(&mutself) -> Option<Self::Item> { ifself.clone_first { self.clone_first = false;
Some(self.item.clone())
} elseiflet next @ Some(_) = self.base.next() { // If there are any items left, we'll need another clone in front. self.clone_first = self.base.len() != 0;
next
} elseifself.clone_last { self.clone_last = false;
Some(self.item.clone())
} else {
None
}
}
fn size_hint(&self) -> (usize, Option<usize>) { let len = self.len();
(len, Some(len))
}
}
impl<I> DoubleEndedIterator for IntersperseIter<I> where
I: DoubleEndedIterator + ExactSizeIterator,
I::Item: Clone,
{ fn next_back(&mutself) -> Option<Self::Item> { ifself.clone_last { self.clone_last = false;
Some(self.item.clone())
} elseiflet next_back @ Some(_) = self.base.next_back() { // If there are any items left, we'll need another clone in back. self.clone_last = self.base.len() != 0;
next_back
} elseifself.clone_first { self.clone_first = false;
Some(self.item.clone())
} else {
None
}
}
}
impl<I> ExactSizeIterator for IntersperseIter<I> where
I: DoubleEndedIterator + ExactSizeIterator,
I::Item: Clone,
{ fn len(&self) -> usize { let len = self.base.len();
len + len.saturating_sub(1) + self.clone_first as usize + self.clone_last as usize
}
}
impl<C, T> Consumer<T> for IntersperseConsumer<C, T> where
C: Consumer<T>,
T: Clone + Send,
{ type Folder = IntersperseFolder<C::Folder, T>; type Reducer = C::Reducer; type Result = C::Result;
fn split_at(mutself, index: usize) -> (Self, Self, Self::Reducer) { // We'll feed twice as many items to the base consumer, except if we're // not currently leading with a cloned item, then it's one less. let base_index = index + index.saturating_sub(!self.clone_first.get() as usize); let (left, right, reducer) = self.base.split_at(base_index);
let right = IntersperseConsumer {
base: right,
item: self.item.clone(),
clone_first: true.into(),
}; self.base = left;
(self, right, reducer)
}
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.