1 use super::plumbing::*; 2 use super::*; 3 4 use std::fmt::{self, Debug}; 5 6 /// `MapWith` is an iterator that transforms the elements of an underlying iterator. 7 /// 8 /// This struct is created by the [`map_with()`] method on [`ParallelIterator`] 9 /// 10 /// [`map_with()`]: trait.ParallelIterator.html#method.map_with 11 /// [`ParallelIterator`]: trait.ParallelIterator.html 12 #[must_use = "iterator adaptors are lazy and do nothing unless consumed"] 13 #[derive(Clone)] 14 pub struct MapWith<I: ParallelIterator, T, F> { 15 base: I, 16 item: T, 17 map_op: F, 18 } 19 20 impl<I: ParallelIterator + Debug, T: Debug, F> Debug for MapWith<I, T, F> { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result21 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 22 f.debug_struct("MapWith") 23 .field("base", &self.base) 24 .field("item", &self.item) 25 .finish() 26 } 27 } 28 29 impl<I, T, F> MapWith<I, T, F> 30 where 31 I: ParallelIterator, 32 { 33 /// Creates a new `MapWith` iterator. new(base: I, item: T, map_op: F) -> Self34 pub(super) fn new(base: I, item: T, map_op: F) -> Self { 35 MapWith { base, item, map_op } 36 } 37 } 38 39 impl<I, T, F, R> ParallelIterator for MapWith<I, T, F> 40 where 41 I: ParallelIterator, 42 T: Send + Clone, 43 F: Fn(&mut T, I::Item) -> R + Sync + Send, 44 R: Send, 45 { 46 type Item = R; 47 drive_unindexed<C>(self, consumer: C) -> C::Result where C: UnindexedConsumer<Self::Item>,48 fn drive_unindexed<C>(self, consumer: C) -> C::Result 49 where 50 C: UnindexedConsumer<Self::Item>, 51 { 52 let consumer1 = MapWithConsumer::new(consumer, self.item, &self.map_op); 53 self.base.drive_unindexed(consumer1) 54 } 55 opt_len(&self) -> Option<usize>56 fn opt_len(&self) -> Option<usize> { 57 self.base.opt_len() 58 } 59 } 60 61 impl<I, T, F, R> IndexedParallelIterator for MapWith<I, T, F> 62 where 63 I: IndexedParallelIterator, 64 T: Send + Clone, 65 F: Fn(&mut T, I::Item) -> R + Sync + Send, 66 R: Send, 67 { drive<C>(self, consumer: C) -> C::Result where C: Consumer<Self::Item>,68 fn drive<C>(self, consumer: C) -> C::Result 69 where 70 C: Consumer<Self::Item>, 71 { 72 let consumer1 = MapWithConsumer::new(consumer, self.item, &self.map_op); 73 self.base.drive(consumer1) 74 } 75 len(&self) -> usize76 fn len(&self) -> usize { 77 self.base.len() 78 } 79 with_producer<CB>(self, callback: CB) -> CB::Output where CB: ProducerCallback<Self::Item>,80 fn with_producer<CB>(self, callback: CB) -> CB::Output 81 where 82 CB: ProducerCallback<Self::Item>, 83 { 84 return self.base.with_producer(Callback { 85 callback, 86 item: self.item, 87 map_op: self.map_op, 88 }); 89 90 struct Callback<CB, U, F> { 91 callback: CB, 92 item: U, 93 map_op: F, 94 } 95 96 impl<T, U, F, R, CB> ProducerCallback<T> for Callback<CB, U, F> 97 where 98 CB: ProducerCallback<R>, 99 U: Send + Clone, 100 F: Fn(&mut U, T) -> R + Sync, 101 R: Send, 102 { 103 type Output = CB::Output; 104 105 fn callback<P>(self, base: P) -> CB::Output 106 where 107 P: Producer<Item = T>, 108 { 109 let producer = MapWithProducer { 110 base, 111 item: self.item, 112 map_op: &self.map_op, 113 }; 114 self.callback.callback(producer) 115 } 116 } 117 } 118 } 119 120 /// //////////////////////////////////////////////////////////////////////// 121 122 struct MapWithProducer<'f, P, U, F> { 123 base: P, 124 item: U, 125 map_op: &'f F, 126 } 127 128 impl<'f, P, U, F, R> Producer for MapWithProducer<'f, P, U, F> 129 where 130 P: Producer, 131 U: Send + Clone, 132 F: Fn(&mut U, P::Item) -> R + Sync, 133 R: Send, 134 { 135 type Item = R; 136 type IntoIter = MapWithIter<'f, P::IntoIter, U, F>; 137 into_iter(self) -> Self::IntoIter138 fn into_iter(self) -> Self::IntoIter { 139 MapWithIter { 140 base: self.base.into_iter(), 141 item: self.item, 142 map_op: self.map_op, 143 } 144 } 145 min_len(&self) -> usize146 fn min_len(&self) -> usize { 147 self.base.min_len() 148 } max_len(&self) -> usize149 fn max_len(&self) -> usize { 150 self.base.max_len() 151 } 152 split_at(self, index: usize) -> (Self, Self)153 fn split_at(self, index: usize) -> (Self, Self) { 154 let (left, right) = self.base.split_at(index); 155 ( 156 MapWithProducer { 157 base: left, 158 item: self.item.clone(), 159 map_op: self.map_op, 160 }, 161 MapWithProducer { 162 base: right, 163 item: self.item, 164 map_op: self.map_op, 165 }, 166 ) 167 } 168 fold_with<G>(self, folder: G) -> G where G: Folder<Self::Item>,169 fn fold_with<G>(self, folder: G) -> G 170 where 171 G: Folder<Self::Item>, 172 { 173 let folder1 = MapWithFolder { 174 base: folder, 175 item: self.item, 176 map_op: self.map_op, 177 }; 178 self.base.fold_with(folder1).base 179 } 180 } 181 182 struct MapWithIter<'f, I, U, F> { 183 base: I, 184 item: U, 185 map_op: &'f F, 186 } 187 188 impl<'f, I, U, F, R> Iterator for MapWithIter<'f, I, U, F> 189 where 190 I: Iterator, 191 F: Fn(&mut U, I::Item) -> R + Sync, 192 R: Send, 193 { 194 type Item = R; 195 next(&mut self) -> Option<R>196 fn next(&mut self) -> Option<R> { 197 let item = self.base.next()?; 198 Some((self.map_op)(&mut self.item, item)) 199 } 200 size_hint(&self) -> (usize, Option<usize>)201 fn size_hint(&self) -> (usize, Option<usize>) { 202 self.base.size_hint() 203 } 204 } 205 206 impl<'f, I, U, F, R> DoubleEndedIterator for MapWithIter<'f, I, U, F> 207 where 208 I: DoubleEndedIterator, 209 F: Fn(&mut U, I::Item) -> R + Sync, 210 R: Send, 211 { next_back(&mut self) -> Option<R>212 fn next_back(&mut self) -> Option<R> { 213 let item = self.base.next_back()?; 214 Some((self.map_op)(&mut self.item, item)) 215 } 216 } 217 218 impl<'f, I, U, F, R> ExactSizeIterator for MapWithIter<'f, I, U, F> 219 where 220 I: ExactSizeIterator, 221 F: Fn(&mut U, I::Item) -> R + Sync, 222 R: Send, 223 { 224 } 225 226 /// //////////////////////////////////////////////////////////////////////// 227 /// Consumer implementation 228 229 struct MapWithConsumer<'f, C, U, F> { 230 base: C, 231 item: U, 232 map_op: &'f F, 233 } 234 235 impl<'f, C, U, F> MapWithConsumer<'f, C, U, F> { new(base: C, item: U, map_op: &'f F) -> Self236 fn new(base: C, item: U, map_op: &'f F) -> Self { 237 MapWithConsumer { base, item, map_op } 238 } 239 } 240 241 impl<'f, T, U, R, C, F> Consumer<T> for MapWithConsumer<'f, C, U, F> 242 where 243 C: Consumer<R>, 244 U: Send + Clone, 245 F: Fn(&mut U, T) -> R + Sync, 246 R: Send, 247 { 248 type Folder = MapWithFolder<'f, C::Folder, U, F>; 249 type Reducer = C::Reducer; 250 type Result = C::Result; 251 split_at(self, index: usize) -> (Self, Self, Self::Reducer)252 fn split_at(self, index: usize) -> (Self, Self, Self::Reducer) { 253 let (left, right, reducer) = self.base.split_at(index); 254 ( 255 MapWithConsumer::new(left, self.item.clone(), self.map_op), 256 MapWithConsumer::new(right, self.item, self.map_op), 257 reducer, 258 ) 259 } 260 into_folder(self) -> Self::Folder261 fn into_folder(self) -> Self::Folder { 262 MapWithFolder { 263 base: self.base.into_folder(), 264 item: self.item, 265 map_op: self.map_op, 266 } 267 } 268 full(&self) -> bool269 fn full(&self) -> bool { 270 self.base.full() 271 } 272 } 273 274 impl<'f, T, U, R, C, F> UnindexedConsumer<T> for MapWithConsumer<'f, C, U, F> 275 where 276 C: UnindexedConsumer<R>, 277 U: Send + Clone, 278 F: Fn(&mut U, T) -> R + Sync, 279 R: Send, 280 { split_off_left(&self) -> Self281 fn split_off_left(&self) -> Self { 282 MapWithConsumer::new(self.base.split_off_left(), self.item.clone(), self.map_op) 283 } 284 to_reducer(&self) -> Self::Reducer285 fn to_reducer(&self) -> Self::Reducer { 286 self.base.to_reducer() 287 } 288 } 289 290 struct MapWithFolder<'f, C, U, F> { 291 base: C, 292 item: U, 293 map_op: &'f F, 294 } 295 296 impl<'f, T, U, R, C, F> Folder<T> for MapWithFolder<'f, C, U, F> 297 where 298 C: Folder<R>, 299 F: Fn(&mut U, T) -> R, 300 { 301 type Result = C::Result; 302 consume(mut self, item: T) -> Self303 fn consume(mut self, item: T) -> Self { 304 let mapped_item = (self.map_op)(&mut self.item, item); 305 self.base = self.base.consume(mapped_item); 306 self 307 } 308 consume_iter<I>(mut self, iter: I) -> Self where I: IntoIterator<Item = T>,309 fn consume_iter<I>(mut self, iter: I) -> Self 310 where 311 I: IntoIterator<Item = T>, 312 { 313 fn with<'f, T, U, R>( 314 item: &'f mut U, 315 map_op: impl Fn(&mut U, T) -> R + 'f, 316 ) -> impl FnMut(T) -> R + 'f { 317 move |x| map_op(item, x) 318 } 319 320 { 321 let mapped_iter = iter.into_iter().map(with(&mut self.item, self.map_op)); 322 self.base = self.base.consume_iter(mapped_iter); 323 } 324 self 325 } 326 complete(self) -> C::Result327 fn complete(self) -> C::Result { 328 self.base.complete() 329 } 330 full(&self) -> bool331 fn full(&self) -> bool { 332 self.base.full() 333 } 334 } 335 336 // ------------------------------------------------------------------------------------------------ 337 338 /// `MapInit` is an iterator that transforms the elements of an underlying iterator. 339 /// 340 /// This struct is created by the [`map_init()`] method on [`ParallelIterator`] 341 /// 342 /// [`map_init()`]: trait.ParallelIterator.html#method.map_init 343 /// [`ParallelIterator`]: trait.ParallelIterator.html 344 #[must_use = "iterator adaptors are lazy and do nothing unless consumed"] 345 #[derive(Clone)] 346 pub struct MapInit<I: ParallelIterator, INIT, F> { 347 base: I, 348 init: INIT, 349 map_op: F, 350 } 351 352 impl<I: ParallelIterator + Debug, INIT, F> Debug for MapInit<I, INIT, F> { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result353 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 354 f.debug_struct("MapInit").field("base", &self.base).finish() 355 } 356 } 357 358 impl<I, INIT, F> MapInit<I, INIT, F> 359 where 360 I: ParallelIterator, 361 { 362 /// Creates a new `MapInit` iterator. new(base: I, init: INIT, map_op: F) -> Self363 pub(super) fn new(base: I, init: INIT, map_op: F) -> Self { 364 MapInit { base, init, map_op } 365 } 366 } 367 368 impl<I, INIT, T, F, R> ParallelIterator for MapInit<I, INIT, F> 369 where 370 I: ParallelIterator, 371 INIT: Fn() -> T + Sync + Send, 372 F: Fn(&mut T, I::Item) -> R + Sync + Send, 373 R: Send, 374 { 375 type Item = R; 376 drive_unindexed<C>(self, consumer: C) -> C::Result where C: UnindexedConsumer<Self::Item>,377 fn drive_unindexed<C>(self, consumer: C) -> C::Result 378 where 379 C: UnindexedConsumer<Self::Item>, 380 { 381 let consumer1 = MapInitConsumer::new(consumer, &self.init, &self.map_op); 382 self.base.drive_unindexed(consumer1) 383 } 384 opt_len(&self) -> Option<usize>385 fn opt_len(&self) -> Option<usize> { 386 self.base.opt_len() 387 } 388 } 389 390 impl<I, INIT, T, F, R> IndexedParallelIterator for MapInit<I, INIT, F> 391 where 392 I: IndexedParallelIterator, 393 INIT: Fn() -> T + Sync + Send, 394 F: Fn(&mut T, I::Item) -> R + Sync + Send, 395 R: Send, 396 { drive<C>(self, consumer: C) -> C::Result where C: Consumer<Self::Item>,397 fn drive<C>(self, consumer: C) -> C::Result 398 where 399 C: Consumer<Self::Item>, 400 { 401 let consumer1 = MapInitConsumer::new(consumer, &self.init, &self.map_op); 402 self.base.drive(consumer1) 403 } 404 len(&self) -> usize405 fn len(&self) -> usize { 406 self.base.len() 407 } 408 with_producer<CB>(self, callback: CB) -> CB::Output where CB: ProducerCallback<Self::Item>,409 fn with_producer<CB>(self, callback: CB) -> CB::Output 410 where 411 CB: ProducerCallback<Self::Item>, 412 { 413 return self.base.with_producer(Callback { 414 callback, 415 init: self.init, 416 map_op: self.map_op, 417 }); 418 419 struct Callback<CB, INIT, F> { 420 callback: CB, 421 init: INIT, 422 map_op: F, 423 } 424 425 impl<T, INIT, U, F, R, CB> ProducerCallback<T> for Callback<CB, INIT, F> 426 where 427 CB: ProducerCallback<R>, 428 INIT: Fn() -> U + Sync, 429 F: Fn(&mut U, T) -> R + Sync, 430 R: Send, 431 { 432 type Output = CB::Output; 433 434 fn callback<P>(self, base: P) -> CB::Output 435 where 436 P: Producer<Item = T>, 437 { 438 let producer = MapInitProducer { 439 base, 440 init: &self.init, 441 map_op: &self.map_op, 442 }; 443 self.callback.callback(producer) 444 } 445 } 446 } 447 } 448 449 /// //////////////////////////////////////////////////////////////////////// 450 451 struct MapInitProducer<'f, P, INIT, F> { 452 base: P, 453 init: &'f INIT, 454 map_op: &'f F, 455 } 456 457 impl<'f, P, INIT, U, F, R> Producer for MapInitProducer<'f, P, INIT, F> 458 where 459 P: Producer, 460 INIT: Fn() -> U + Sync, 461 F: Fn(&mut U, P::Item) -> R + Sync, 462 R: Send, 463 { 464 type Item = R; 465 type IntoIter = MapWithIter<'f, P::IntoIter, U, F>; 466 into_iter(self) -> Self::IntoIter467 fn into_iter(self) -> Self::IntoIter { 468 MapWithIter { 469 base: self.base.into_iter(), 470 item: (self.init)(), 471 map_op: self.map_op, 472 } 473 } 474 min_len(&self) -> usize475 fn min_len(&self) -> usize { 476 self.base.min_len() 477 } max_len(&self) -> usize478 fn max_len(&self) -> usize { 479 self.base.max_len() 480 } 481 split_at(self, index: usize) -> (Self, Self)482 fn split_at(self, index: usize) -> (Self, Self) { 483 let (left, right) = self.base.split_at(index); 484 ( 485 MapInitProducer { 486 base: left, 487 init: self.init, 488 map_op: self.map_op, 489 }, 490 MapInitProducer { 491 base: right, 492 init: self.init, 493 map_op: self.map_op, 494 }, 495 ) 496 } 497 fold_with<G>(self, folder: G) -> G where G: Folder<Self::Item>,498 fn fold_with<G>(self, folder: G) -> G 499 where 500 G: Folder<Self::Item>, 501 { 502 let folder1 = MapWithFolder { 503 base: folder, 504 item: (self.init)(), 505 map_op: self.map_op, 506 }; 507 self.base.fold_with(folder1).base 508 } 509 } 510 511 /// //////////////////////////////////////////////////////////////////////// 512 /// Consumer implementation 513 514 struct MapInitConsumer<'f, C, INIT, F> { 515 base: C, 516 init: &'f INIT, 517 map_op: &'f F, 518 } 519 520 impl<'f, C, INIT, F> MapInitConsumer<'f, C, INIT, F> { new(base: C, init: &'f INIT, map_op: &'f F) -> Self521 fn new(base: C, init: &'f INIT, map_op: &'f F) -> Self { 522 MapInitConsumer { base, init, map_op } 523 } 524 } 525 526 impl<'f, T, INIT, U, R, C, F> Consumer<T> for MapInitConsumer<'f, C, INIT, F> 527 where 528 C: Consumer<R>, 529 INIT: Fn() -> U + Sync, 530 F: Fn(&mut U, T) -> R + Sync, 531 R: Send, 532 { 533 type Folder = MapWithFolder<'f, C::Folder, U, F>; 534 type Reducer = C::Reducer; 535 type Result = C::Result; 536 split_at(self, index: usize) -> (Self, Self, Self::Reducer)537 fn split_at(self, index: usize) -> (Self, Self, Self::Reducer) { 538 let (left, right, reducer) = self.base.split_at(index); 539 ( 540 MapInitConsumer::new(left, self.init, self.map_op), 541 MapInitConsumer::new(right, self.init, self.map_op), 542 reducer, 543 ) 544 } 545 into_folder(self) -> Self::Folder546 fn into_folder(self) -> Self::Folder { 547 MapWithFolder { 548 base: self.base.into_folder(), 549 item: (self.init)(), 550 map_op: self.map_op, 551 } 552 } 553 full(&self) -> bool554 fn full(&self) -> bool { 555 self.base.full() 556 } 557 } 558 559 impl<'f, T, INIT, U, R, C, F> UnindexedConsumer<T> for MapInitConsumer<'f, C, INIT, F> 560 where 561 C: UnindexedConsumer<R>, 562 INIT: Fn() -> U + Sync, 563 F: Fn(&mut U, T) -> R + Sync, 564 R: Send, 565 { split_off_left(&self) -> Self566 fn split_off_left(&self) -> Self { 567 MapInitConsumer::new(self.base.split_off_left(), self.init, self.map_op) 568 } 569 to_reducer(&self) -> Self::Reducer570 fn to_reducer(&self) -> Self::Reducer { 571 self.base.to_reducer() 572 } 573 } 574