1 use super::plumbing::*; 2 use super::*; 3 4 use std::fmt::{self, Debug}; 5 use std::iter; 6 7 /// `Map` is an iterator that transforms the elements of an underlying iterator. 8 /// 9 /// This struct is created by the [`map()`] method on [`ParallelIterator`] 10 /// 11 /// [`map()`]: trait.ParallelIterator.html#method.map 12 /// [`ParallelIterator`]: trait.ParallelIterator.html 13 #[must_use = "iterator adaptors are lazy and do nothing unless consumed"] 14 #[derive(Clone)] 15 pub struct Map<I: ParallelIterator, F> { 16 base: I, 17 map_op: F, 18 } 19 20 impl<I: ParallelIterator + Debug, F> Debug for Map<I, F> { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result21 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 22 f.debug_struct("Map").field("base", &self.base).finish() 23 } 24 } 25 26 impl<I, F> Map<I, F> 27 where 28 I: ParallelIterator, 29 { 30 /// Creates a new `Map` iterator. new(base: I, map_op: F) -> Self31 pub(super) fn new(base: I, map_op: F) -> Self { 32 Map { base, map_op } 33 } 34 } 35 36 impl<I, F, R> ParallelIterator for Map<I, F> 37 where 38 I: ParallelIterator, 39 F: Fn(I::Item) -> R + Sync + Send, 40 R: Send, 41 { 42 type Item = F::Output; 43 drive_unindexed<C>(self, consumer: C) -> C::Result where C: UnindexedConsumer<Self::Item>,44 fn drive_unindexed<C>(self, consumer: C) -> C::Result 45 where 46 C: UnindexedConsumer<Self::Item>, 47 { 48 let consumer1 = MapConsumer::new(consumer, &self.map_op); 49 self.base.drive_unindexed(consumer1) 50 } 51 opt_len(&self) -> Option<usize>52 fn opt_len(&self) -> Option<usize> { 53 self.base.opt_len() 54 } 55 } 56 57 impl<I, F, R> IndexedParallelIterator for Map<I, F> 58 where 59 I: IndexedParallelIterator, 60 F: Fn(I::Item) -> R + Sync + Send, 61 R: Send, 62 { drive<C>(self, consumer: C) -> C::Result where C: Consumer<Self::Item>,63 fn drive<C>(self, consumer: C) -> C::Result 64 where 65 C: Consumer<Self::Item>, 66 { 67 let consumer1 = MapConsumer::new(consumer, &self.map_op); 68 self.base.drive(consumer1) 69 } 70 len(&self) -> usize71 fn len(&self) -> usize { 72 self.base.len() 73 } 74 with_producer<CB>(self, callback: CB) -> CB::Output where CB: ProducerCallback<Self::Item>,75 fn with_producer<CB>(self, callback: CB) -> CB::Output 76 where 77 CB: ProducerCallback<Self::Item>, 78 { 79 return self.base.with_producer(Callback { 80 callback, 81 map_op: self.map_op, 82 }); 83 84 struct Callback<CB, F> { 85 callback: CB, 86 map_op: F, 87 } 88 89 impl<T, F, R, CB> ProducerCallback<T> for Callback<CB, F> 90 where 91 CB: ProducerCallback<R>, 92 F: Fn(T) -> R + Sync, 93 R: Send, 94 { 95 type Output = CB::Output; 96 97 fn callback<P>(self, base: P) -> CB::Output 98 where 99 P: Producer<Item = T>, 100 { 101 let producer = MapProducer { 102 base, 103 map_op: &self.map_op, 104 }; 105 self.callback.callback(producer) 106 } 107 } 108 } 109 } 110 111 /// //////////////////////////////////////////////////////////////////////// 112 113 struct MapProducer<'f, P, F> { 114 base: P, 115 map_op: &'f F, 116 } 117 118 impl<'f, P, F, R> Producer for MapProducer<'f, P, F> 119 where 120 P: Producer, 121 F: Fn(P::Item) -> R + Sync, 122 R: Send, 123 { 124 type Item = F::Output; 125 type IntoIter = iter::Map<P::IntoIter, &'f F>; 126 into_iter(self) -> Self::IntoIter127 fn into_iter(self) -> Self::IntoIter { 128 self.base.into_iter().map(self.map_op) 129 } 130 min_len(&self) -> usize131 fn min_len(&self) -> usize { 132 self.base.min_len() 133 } max_len(&self) -> usize134 fn max_len(&self) -> usize { 135 self.base.max_len() 136 } 137 split_at(self, index: usize) -> (Self, Self)138 fn split_at(self, index: usize) -> (Self, Self) { 139 let (left, right) = self.base.split_at(index); 140 ( 141 MapProducer { 142 base: left, 143 map_op: self.map_op, 144 }, 145 MapProducer { 146 base: right, 147 map_op: self.map_op, 148 }, 149 ) 150 } 151 fold_with<G>(self, folder: G) -> G where G: Folder<Self::Item>,152 fn fold_with<G>(self, folder: G) -> G 153 where 154 G: Folder<Self::Item>, 155 { 156 let folder1 = MapFolder { 157 base: folder, 158 map_op: self.map_op, 159 }; 160 self.base.fold_with(folder1).base 161 } 162 } 163 164 /// //////////////////////////////////////////////////////////////////////// 165 /// Consumer implementation 166 167 struct MapConsumer<'f, C, F> { 168 base: C, 169 map_op: &'f F, 170 } 171 172 impl<'f, C, F> MapConsumer<'f, C, F> { new(base: C, map_op: &'f F) -> Self173 fn new(base: C, map_op: &'f F) -> Self { 174 MapConsumer { base, map_op } 175 } 176 } 177 178 impl<'f, T, R, C, F> Consumer<T> for MapConsumer<'f, C, F> 179 where 180 C: Consumer<F::Output>, 181 F: Fn(T) -> R + Sync, 182 R: Send, 183 { 184 type Folder = MapFolder<'f, C::Folder, F>; 185 type Reducer = C::Reducer; 186 type Result = C::Result; 187 split_at(self, index: usize) -> (Self, Self, Self::Reducer)188 fn split_at(self, index: usize) -> (Self, Self, Self::Reducer) { 189 let (left, right, reducer) = self.base.split_at(index); 190 ( 191 MapConsumer::new(left, self.map_op), 192 MapConsumer::new(right, self.map_op), 193 reducer, 194 ) 195 } 196 into_folder(self) -> Self::Folder197 fn into_folder(self) -> Self::Folder { 198 MapFolder { 199 base: self.base.into_folder(), 200 map_op: self.map_op, 201 } 202 } 203 full(&self) -> bool204 fn full(&self) -> bool { 205 self.base.full() 206 } 207 } 208 209 impl<'f, T, R, C, F> UnindexedConsumer<T> for MapConsumer<'f, C, F> 210 where 211 C: UnindexedConsumer<F::Output>, 212 F: Fn(T) -> R + Sync, 213 R: Send, 214 { split_off_left(&self) -> Self215 fn split_off_left(&self) -> Self { 216 MapConsumer::new(self.base.split_off_left(), &self.map_op) 217 } 218 to_reducer(&self) -> Self::Reducer219 fn to_reducer(&self) -> Self::Reducer { 220 self.base.to_reducer() 221 } 222 } 223 224 struct MapFolder<'f, C, F> { 225 base: C, 226 map_op: &'f F, 227 } 228 229 impl<'f, T, R, C, F> Folder<T> for MapFolder<'f, C, F> 230 where 231 C: Folder<F::Output>, 232 F: Fn(T) -> R, 233 { 234 type Result = C::Result; 235 consume(self, item: T) -> Self236 fn consume(self, item: T) -> Self { 237 let mapped_item = (self.map_op)(item); 238 MapFolder { 239 base: self.base.consume(mapped_item), 240 map_op: self.map_op, 241 } 242 } 243 consume_iter<I>(mut self, iter: I) -> Self where I: IntoIterator<Item = T>,244 fn consume_iter<I>(mut self, iter: I) -> Self 245 where 246 I: IntoIterator<Item = T>, 247 { 248 self.base = self.base.consume_iter(iter.into_iter().map(self.map_op)); 249 self 250 } 251 complete(self) -> C::Result252 fn complete(self) -> C::Result { 253 self.base.complete() 254 } 255 full(&self) -> bool256 fn full(&self) -> bool { 257 self.base.full() 258 } 259 } 260