use crate::{ Consumer, Executor, Folder, IndexedParallelIterator, IndexedProducer, IndexedProducerCallback, ParallelIterator, Producer, ProducerCallback, Reducer, Setup, WithIndexedProducer, WithProducer, WithSetup, }; pub struct Splits { base: X, splits: usize, } impl Splits { pub fn new(base: X, splits: usize) -> Self { Self { base, splits } } } impl<'a, X> ParallelIterator<'a> for Splits where X: ParallelIterator<'a>, { type Item = X::Item; fn drive(self, executor: E, base: C) -> E::Result where E: Executor<'a, D>, C: Consumer + 'a, D: Send + 'a, R: Reducer + Send + 'a, { let splits = self.splits; let consumer = SplitsConsumer { base, splits }; self.base.drive(executor, consumer) } fn len_hint_opt(&self) -> Option { self.base.len_hint_opt() } } impl<'a, X> IndexedParallelIterator<'a> for Splits where X: IndexedParallelIterator<'a>, { fn drive_indexed(self, executor: E, base: C) -> E::Result where E: Executor<'a, D>, C: Consumer + 'a, D: Send + 'a, R: Reducer + Send + 'a, { let splits = self.splits; let consumer = SplitsConsumer { base, splits }; self.base.drive_indexed(executor, consumer) } fn len_hint(&self) -> usize { self.base.len_hint() } } impl<'a, X> WithProducer<'a> for Splits where X: WithProducer<'a>, { type Item = X::Item; fn with_producer(self, base: CB) -> CB::Output where CB: ProducerCallback<'a, Self::Item>, { let splits = self.splits; self.base.with_producer(SplitsCallback { base, splits }) } } impl<'a, X> WithIndexedProducer<'a> for Splits where X: WithIndexedProducer<'a>, { type Item = X::Item; fn with_indexed_producer(self, base: CB) -> CB::Output where CB: IndexedProducerCallback<'a, Self::Item>, { let splits = self.splits; self.base .with_indexed_producer(SplitsCallback { base, splits }) } } /* SplitsCallback */ struct SplitsCallback { base: CB, splits: usize, } impl<'a, CB, I> ProducerCallback<'a, I> for SplitsCallback where CB: ProducerCallback<'a, I>, { type Output = CB::Output; fn callback

(self, base: P) -> Self::Output where P: Producer + 'a, { let splits = self.splits; self.base.callback(SplitsProducer { base, splits }) } } impl<'a, CB, I> IndexedProducerCallback<'a, I> for SplitsCallback where CB: IndexedProducerCallback<'a, I>, { type Output = CB::Output; fn callback

(self, base: P) -> Self::Output where P: IndexedProducer + 'a, { let splits = self.splits; self.base.callback(SplitsProducer { base, splits }) } } /* SplitsProducer */ struct SplitsProducer

{ base: P, splits: usize, } impl

WithSetup for SplitsProducer

where P: WithSetup, { fn setup(&self) -> Setup { self.base.setup().merge(Setup { splits: Some(self.splits), ..Default::default() }) } } impl

Producer for SplitsProducer

where P: Producer, { type Item = P::Item; type IntoIter = P::IntoIter; fn into_iter(self) -> Self::IntoIter { self.base.into_iter() } fn split(self) -> (Self, Option) { let splits = self.splits; let (left, right) = self.base.split(); let left = Self { base: left, splits }; let right = right.map(|base| Self { base, splits }); (left, right) } fn fold_with(self, folder: F) -> F where F: Folder, { self.base.fold_with(folder) } } impl

IndexedProducer for SplitsProducer

where P: IndexedProducer, { type Item = P::Item; type IntoIter = P::IntoIter; fn into_iter(self) -> Self::IntoIter { self.base.into_iter() } fn len(&self) -> usize { self.base.len() } fn split_at(self, index: usize) -> (Self, Self) { let splits = self.splits; let (left, right) = self.base.split_at(index); let left = Self { base: left, splits }; let right = Self { base: right, splits, }; (left, right) } fn fold_with(self, folder: F) -> F where F: Folder, { self.base.fold_with(folder) } } /* SplitsConsumer */ struct SplitsConsumer { base: C, splits: usize, } impl WithSetup for SplitsConsumer where C: WithSetup, { fn setup(&self) -> Setup { self.base.setup().merge(Setup { splits: Some(self.splits), ..Default::default() }) } } impl Consumer for SplitsConsumer where C: Consumer, { type Folder = C::Folder; type Reducer = C::Reducer; type Result = C::Result; fn split(self) -> (Self, Self, Self::Reducer) { let splits = self.splits; let (left, right, reducer) = self.base.split(); let left = Self { base: left, splits }; let right = Self { base: right, splits, }; (left, right, reducer) } fn split_at(self, index: usize) -> (Self, Self, Self::Reducer) { let splits = self.splits; let (left, right, reducer) = self.base.split_at(index); let left = Self { base: left, splits }; let right = Self { base: right, splits, }; (left, right, reducer) } fn into_folder(self) -> Self::Folder { self.base.into_folder() } fn is_full(&self) -> bool { self.base.is_full() } }