1 use super::plumbing::*; 2 use super::*; 3 4 use std::iter; 5 6 /// `Cloned` is an iterator that clones the elements of an underlying iterator. 7 /// 8 /// This struct is created by the [`cloned()`] method on [`ParallelIterator`] 9 /// 10 /// [`cloned()`]: trait.ParallelIterator.html#method.cloned 11 /// [`ParallelIterator`]: trait.ParallelIterator.html 12 #[must_use = "iterator adaptors are lazy and do nothing unless consumed"] 13 #[derive(Debug, Clone)] 14 pub struct Cloned<I: ParallelIterator> { 15 base: I, 16 } 17 18 impl<I> Cloned<I> 19 where 20 I: ParallelIterator, 21 { 22 /// Creates a new `Cloned` iterator. new(base: I) -> Self23 pub(super) fn new(base: I) -> Self { 24 Cloned { base } 25 } 26 } 27 28 impl<'a, T, I> ParallelIterator for Cloned<I> 29 where 30 I: ParallelIterator<Item = &'a T>, 31 T: 'a + Clone + Send + Sync, 32 { 33 type Item = T; 34 drive_unindexed<C>(self, consumer: C) -> C::Result where C: UnindexedConsumer<Self::Item>,35 fn drive_unindexed<C>(self, consumer: C) -> C::Result 36 where 37 C: UnindexedConsumer<Self::Item>, 38 { 39 let consumer1 = ClonedConsumer::new(consumer); 40 self.base.drive_unindexed(consumer1) 41 } 42 opt_len(&self) -> Option<usize>43 fn opt_len(&self) -> Option<usize> { 44 self.base.opt_len() 45 } 46 } 47 48 impl<'a, T, I> IndexedParallelIterator for Cloned<I> 49 where 50 I: IndexedParallelIterator<Item = &'a T>, 51 T: 'a + Clone + Send + Sync, 52 { drive<C>(self, consumer: C) -> C::Result where C: Consumer<Self::Item>,53 fn drive<C>(self, consumer: C) -> C::Result 54 where 55 C: Consumer<Self::Item>, 56 { 57 let consumer1 = ClonedConsumer::new(consumer); 58 self.base.drive(consumer1) 59 } 60 len(&self) -> usize61 fn len(&self) -> usize { 62 self.base.len() 63 } 64 with_producer<CB>(self, callback: CB) -> CB::Output where CB: ProducerCallback<Self::Item>,65 fn with_producer<CB>(self, callback: CB) -> CB::Output 66 where 67 CB: ProducerCallback<Self::Item>, 68 { 69 return self.base.with_producer(Callback { callback }); 70 71 struct Callback<CB> { 72 callback: CB, 73 } 74 75 impl<'a, T, CB> ProducerCallback<&'a T> for Callback<CB> 76 where 77 CB: ProducerCallback<T>, 78 T: 'a + Clone + Send, 79 { 80 type Output = CB::Output; 81 82 fn callback<P>(self, base: P) -> CB::Output 83 where 84 P: Producer<Item = &'a T>, 85 { 86 let producer = ClonedProducer { base }; 87 self.callback.callback(producer) 88 } 89 } 90 } 91 } 92 93 /// //////////////////////////////////////////////////////////////////////// 94 95 struct ClonedProducer<P> { 96 base: P, 97 } 98 99 impl<'a, T, P> Producer for ClonedProducer<P> 100 where 101 P: Producer<Item = &'a T>, 102 T: 'a + Clone, 103 { 104 type Item = T; 105 type IntoIter = iter::Cloned<P::IntoIter>; 106 into_iter(self) -> Self::IntoIter107 fn into_iter(self) -> Self::IntoIter { 108 self.base.into_iter().cloned() 109 } 110 min_len(&self) -> usize111 fn min_len(&self) -> usize { 112 self.base.min_len() 113 } 114 max_len(&self) -> usize115 fn max_len(&self) -> usize { 116 self.base.max_len() 117 } 118 split_at(self, index: usize) -> (Self, Self)119 fn split_at(self, index: usize) -> (Self, Self) { 120 let (left, right) = self.base.split_at(index); 121 ( 122 ClonedProducer { base: left }, 123 ClonedProducer { base: right }, 124 ) 125 } 126 fold_with<F>(self, folder: F) -> F where F: Folder<Self::Item>,127 fn fold_with<F>(self, folder: F) -> F 128 where 129 F: Folder<Self::Item>, 130 { 131 self.base.fold_with(ClonedFolder { base: folder }).base 132 } 133 } 134 135 /// //////////////////////////////////////////////////////////////////////// 136 /// Consumer implementation 137 138 struct ClonedConsumer<C> { 139 base: C, 140 } 141 142 impl<C> ClonedConsumer<C> { new(base: C) -> Self143 fn new(base: C) -> Self { 144 ClonedConsumer { base } 145 } 146 } 147 148 impl<'a, T, C> Consumer<&'a T> for ClonedConsumer<C> 149 where 150 C: Consumer<T>, 151 T: 'a + Clone, 152 { 153 type Folder = ClonedFolder<C::Folder>; 154 type Reducer = C::Reducer; 155 type Result = C::Result; 156 split_at(self, index: usize) -> (Self, Self, Self::Reducer)157 fn split_at(self, index: usize) -> (Self, Self, Self::Reducer) { 158 let (left, right, reducer) = self.base.split_at(index); 159 ( 160 ClonedConsumer::new(left), 161 ClonedConsumer::new(right), 162 reducer, 163 ) 164 } 165 into_folder(self) -> Self::Folder166 fn into_folder(self) -> Self::Folder { 167 ClonedFolder { 168 base: self.base.into_folder(), 169 } 170 } 171 full(&self) -> bool172 fn full(&self) -> bool { 173 self.base.full() 174 } 175 } 176 177 impl<'a, T, C> UnindexedConsumer<&'a T> for ClonedConsumer<C> 178 where 179 C: UnindexedConsumer<T>, 180 T: 'a + Clone, 181 { split_off_left(&self) -> Self182 fn split_off_left(&self) -> Self { 183 ClonedConsumer::new(self.base.split_off_left()) 184 } 185 to_reducer(&self) -> Self::Reducer186 fn to_reducer(&self) -> Self::Reducer { 187 self.base.to_reducer() 188 } 189 } 190 191 struct ClonedFolder<F> { 192 base: F, 193 } 194 195 impl<'a, T, F> Folder<&'a T> for ClonedFolder<F> 196 where 197 F: Folder<T>, 198 T: 'a + Clone, 199 { 200 type Result = F::Result; 201 consume(self, item: &'a T) -> Self202 fn consume(self, item: &'a T) -> Self { 203 ClonedFolder { 204 base: self.base.consume(item.clone()), 205 } 206 } 207 consume_iter<I>(mut self, iter: I) -> Self where I: IntoIterator<Item = &'a T>,208 fn consume_iter<I>(mut self, iter: I) -> Self 209 where 210 I: IntoIterator<Item = &'a T>, 211 { 212 self.base = self.base.consume_iter(iter.into_iter().cloned()); 213 self 214 } 215 complete(self) -> F::Result216 fn complete(self) -> F::Result { 217 self.base.complete() 218 } 219 full(&self) -> bool220 fn full(&self) -> bool { 221 self.base.full() 222 } 223 } 224