use super::noop::NoopConsumer; use super::plumbing::*; use super::*; use std::cmp::min; /// `Skip` is an iterator that skips over the first `n` elements. /// This struct is created by the [`skip()`] method on [`IndexedParallelIterator`] /// /// [`skip()`]: trait.IndexedParallelIterator.html#method.skip /// [`IndexedParallelIterator`]: trait.IndexedParallelIterator.html #[must_use = "iterator adaptors are lazy and do nothing unless consumed"] #[derive(Debug, Clone)] pub struct Skip { base: I, n: usize, } impl Skip where I: IndexedParallelIterator, { /// Creates a new `Skip` iterator. pub(super) fn new(base: I, n: usize) -> Self { let n = min(base.len(), n); Skip { base, n } } } impl ParallelIterator for Skip where I: IndexedParallelIterator, { type Item = I::Item; fn drive_unindexed(self, consumer: C) -> C::Result where C: UnindexedConsumer, { bridge(self, consumer) } fn opt_len(&self) -> Option { Some(self.len()) } } impl IndexedParallelIterator for Skip where I: IndexedParallelIterator, { fn len(&self) -> usize { self.base.len() - self.n } fn drive>(self, consumer: C) -> C::Result { bridge(self, consumer) } fn with_producer(self, callback: CB) -> CB::Output where CB: ProducerCallback, { return self.base.with_producer(Callback { callback, n: self.n, }); struct Callback { callback: CB, n: usize, } impl ProducerCallback for Callback where CB: ProducerCallback, { type Output = CB::Output; fn callback

(self, base: P) -> CB::Output where P: Producer, { crate::in_place_scope(|scope| { let Self { callback, n } = self; let (before_skip, after_skip) = base.split_at(n); // Run the skipped part separately for side effects. // We'll still get any panics propagated back by the scope. scope.spawn(move |_| bridge_producer_consumer(n, before_skip, NoopConsumer)); callback.callback(after_skip) }) } } } }