| 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> { | 
| 21 |     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | 
| 22 |         f.debug_struct("Map" ).field(name:"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. | 
| 31 |     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 |  | 
| 44 |     fn drive_unindexed<C>(self, consumer: C) -> C::Result | 
| 45 |     where | 
| 46 |         C: UnindexedConsumer<Self::Item>, | 
| 47 |     { | 
| 48 |         let consumer1: MapConsumer<'_, C, F> = MapConsumer::new(base:consumer, &self.map_op); | 
| 49 |         self.base.drive_unindexed(consumer:consumer1) | 
| 50 |     } | 
| 51 |  | 
| 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 | { | 
| 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 |  | 
| 71 |     fn len(&self) -> usize { | 
| 72 |         self.base.len() | 
| 73 |     } | 
| 74 |  | 
| 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 |  | 
| 127 |     fn into_iter(self) -> Self::IntoIter { | 
| 128 |         self.base.into_iter().map(self.map_op) | 
| 129 |     } | 
| 130 |  | 
| 131 |     fn min_len(&self) -> usize { | 
| 132 |         self.base.min_len() | 
| 133 |     } | 
| 134 |     fn max_len(&self) -> usize { | 
| 135 |         self.base.max_len() | 
| 136 |     } | 
| 137 |  | 
| 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 |  | 
| 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> { | 
| 173 |     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 |  | 
| 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 |  | 
| 197 |     fn into_folder(self) -> Self::Folder { | 
| 198 |         MapFolder { | 
| 199 |             base: self.base.into_folder(), | 
| 200 |             map_op: self.map_op, | 
| 201 |         } | 
| 202 |     } | 
| 203 |  | 
| 204 |     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 | { | 
| 215 |     fn split_off_left(&self) -> Self { | 
| 216 |         MapConsumer::new(self.base.split_off_left(), self.map_op) | 
| 217 |     } | 
| 218 |  | 
| 219 |     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 |  | 
| 236 |     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 |  | 
| 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 |  | 
| 252 |     fn complete(self) -> C::Result { | 
| 253 |         self.base.complete() | 
| 254 |     } | 
| 255 |  | 
| 256 |     fn full(&self) -> bool { | 
| 257 |         self.base.full() | 
| 258 |     } | 
| 259 | } | 
| 260 |  |