use crate::{ Consumer, Executor, Folder, IndexedParallelIterator, IndexedProducer, IndexedProducerCallback, ParallelIterator, Producer, ProducerCallback, Reducer, Setup, WithIndexedProducer, WithProducer, WithSetup, }; /* Copied */ pub struct Copied { base: X, } impl Copied { pub fn new(base: X) -> Self { Self { base } } } impl<'a, X, T> ParallelIterator<'a> for Copied where X: ParallelIterator<'a, Item = &'a T>, T: Copy + Send + Sync + 'a, { type Item = T; fn drive(self, executor: E, consumer: C) -> E::Result where E: Executor<'a, D>, C: Consumer + 'a, D: Send + 'a, R: Reducer + Send + 'a, { self.base.drive(executor, CopiedConsumer { base: consumer }) } fn len_hint_opt(&self) -> Option { self.base.len_hint_opt() } } impl<'a, X, T> IndexedParallelIterator<'a> for Copied where X: IndexedParallelIterator<'a, Item = &'a T>, T: Copy + Send + Sync + 'a, { fn drive_indexed(self, executor: E, consumer: C) -> E::Result where E: Executor<'a, D>, C: Consumer + 'a, D: Send + 'a, R: Reducer + Send + 'a, { self.base .drive_indexed(executor, CopiedConsumer { base: consumer }) } fn len_hint(&self) -> usize { self.base.len_hint() } } impl<'a, X, T> WithProducer<'a> for Copied where X: WithProducer<'a, Item = &'a T>, T: Copy + Send + Sync + 'a, { type Item = T; fn with_producer(self, callback: CB) -> CB::Output where CB: ProducerCallback<'a, Self::Item>, { self.base.with_producer(CopiedCallback { base: callback }) } } impl<'a, X, T> WithIndexedProducer<'a> for Copied where X: WithIndexedProducer<'a, Item = &'a T>, T: Copy + Send + Sync + 'a, { type Item = T; fn with_indexed_producer(self, callback: CB) -> CB::Output where CB: IndexedProducerCallback<'a, Self::Item>, { self.base .with_indexed_producer(CopiedCallback { base: callback }) } } /* CopiedConsumer */ struct CopiedConsumer { base: C, } impl WithSetup for CopiedConsumer where C: WithSetup, { fn setup(&self) -> Setup { self.base.setup() } } impl<'a, T, C> Consumer<&'a T> for CopiedConsumer where T: Copy, C: Consumer, { type Folder = CopiedFolder; type Reducer = C::Reducer; type Result = C::Result; fn split(self) -> (Self, Self, Self::Reducer) { let (left, right, reducer) = self.base.split(); let left = CopiedConsumer { base: left }; let right = CopiedConsumer { base: right }; (left, right, reducer) } fn split_at(self, index: usize) -> (Self, Self, Self::Reducer) { let (left, right, reducer) = self.base.split_at(index); let left = CopiedConsumer { base: left }; let right = CopiedConsumer { base: right }; (left, right, reducer) } fn into_folder(self) -> Self::Folder { CopiedFolder { base: self.base.into_folder(), } } fn is_full(&self) -> bool { self.base.is_full() } } /* CopiedFolder */ struct CopiedFolder { base: F, } impl<'a, T, F> Folder<&'a T> for CopiedFolder where T: Copy + 'a, F: Folder, { type Result = F::Result; fn consume(mut self, item: &'a T) -> Self { self.base = self.base.consume(*item); self } fn consume_iter(mut self, iter: X) -> Self where X: IntoIterator, { self.base = self.base.consume_iter(iter.into_iter().copied()); self } fn complete(self) -> Self::Result { self.base.complete() } fn is_full(&self) -> bool { self.base.is_full() } } /* CopiedCallback */ struct CopiedCallback { base: CB, } impl<'a, T, CB> ProducerCallback<'a, &'a T> for CopiedCallback where T: Copy + 'a, CB: ProducerCallback<'a, T>, { type Output = CB::Output; fn callback

(self, producer: P) -> Self::Output where P: Producer + 'a, { self.base.callback(CopiedProducer { base: producer }) } } impl<'a, T, CB> IndexedProducerCallback<'a, &'a T> for CopiedCallback where T: Copy + 'a, CB: IndexedProducerCallback<'a, T>, { type Output = CB::Output; fn callback

(self, producer: P) -> Self::Output where P: IndexedProducer + 'a, { self.base.callback(CopiedProducer { base: producer }) } } /* CopiedProducer */ struct CopiedProducer

{ base: P, } impl

WithSetup for CopiedProducer

where P: WithSetup, { fn setup(&self) -> Setup { self.base.setup() } } impl<'a, T, P> Producer for CopiedProducer

where T: Copy + 'a, P: Producer, { type Item = T; type IntoIter = std::iter::Copied; fn into_iter(self) -> Self::IntoIter { self.base.into_iter().copied() } fn split(self) -> (Self, Option) { let (left, right) = self.base.split(); let left = CopiedProducer { base: left }; let right = right.map(|right| CopiedProducer { base: right }); (left, right) } fn fold_with(self, folder: F) -> F where F: Folder, { self.base.fold_with(CopiedFolder { base: folder }).base } } impl<'a, T, P> IndexedProducer for CopiedProducer

where T: Copy + 'a, P: IndexedProducer, { type Item = T; type IntoIter = std::iter::Copied; fn into_iter(self) -> Self::IntoIter { self.base.into_iter().copied() } fn len(&self) -> usize { self.base.len() } fn split_at(self, index: usize) -> (Self, Self) { let (left, right) = self.base.split_at(index); let left = CopiedProducer { base: left }; let right = CopiedProducer { base: right }; (left, right) } fn fold_with(self, folder: F) -> F where F: Folder, { self.base.fold_with(CopiedFolder { base: folder }).base } }