1 | //! This module contains the parallel iterator types for owned strings |
2 | //! (`String`). You will rarely need to interact with it directly |
3 | //! unless you have need to name one of the iterator types. |
4 | |
5 | use crate::iter::plumbing::*; |
6 | use crate::math::simplify_range; |
7 | use crate::prelude::*; |
8 | use std::ops::{Range, RangeBounds}; |
9 | |
10 | impl<'a> ParallelDrainRange<usize> for &'a mut String { |
11 | type Iter = Drain<'a>; |
12 | type Item = char; |
13 | |
14 | fn par_drain<R: RangeBounds<usize>>(self, range: R) -> Self::Iter { |
15 | Drain { |
16 | range: simplify_range(range, self.len()), |
17 | string: self, |
18 | } |
19 | } |
20 | } |
21 | |
22 | /// Draining parallel iterator that moves a range of characters out of a string, |
23 | /// but keeps the total capacity. |
24 | #[derive(Debug)] |
25 | pub struct Drain<'a> { |
26 | string: &'a mut String, |
27 | range: Range<usize>, |
28 | } |
29 | |
30 | impl<'a> ParallelIterator for Drain<'a> { |
31 | type Item = char; |
32 | |
33 | fn drive_unindexed<C>(self, consumer: C) -> C::Result |
34 | where |
35 | C: UnindexedConsumer<Self::Item>, |
36 | { |
37 | self.string[self.range.clone()] |
38 | .par_chars() |
39 | .drive_unindexed(consumer) |
40 | } |
41 | } |
42 | |
43 | impl<'a> Drop for Drain<'a> { |
44 | fn drop(&mut self) { |
45 | // Remove the drained range. |
46 | self.string.drain(self.range.clone()); |
47 | } |
48 | } |
49 | |