]>
Commit | Line | Data |
---|---|---|
2c00a5a8 XL |
1 | use super::plumbing::*; |
2 | use super::*; | |
3 | use std::iter; | |
4 | use std::ops::Range; | |
5 | use std::usize; | |
6 | ||
7 | /// `Enumerate` is an iterator that returns the current count along with the element. | |
8 | /// This struct is created by the [`enumerate()`] method on [`IndexedParallelIterator`] | |
9 | /// | |
10 | /// [`enumerate()`]: trait.IndexedParallelIterator.html#method.enumerate | |
11 | /// [`IndexedParallelIterator`]: trait.IndexedParallelIterator.html | |
12 | #[must_use = "iterator adaptors are lazy and do nothing unless consumed"] | |
13 | #[derive(Debug, Clone)] | |
14 | pub struct Enumerate<I: IndexedParallelIterator> { | |
15 | base: I, | |
16 | } | |
17 | ||
18 | /// Create a new `Enumerate` iterator. | |
19 | /// | |
20 | /// NB: a free fn because it is NOT part of the end-user API. | |
21 | pub fn new<I>(base: I) -> Enumerate<I> | |
22 | where I: IndexedParallelIterator | |
23 | { | |
24 | Enumerate { base: base } | |
25 | } | |
26 | ||
27 | impl<I> ParallelIterator for Enumerate<I> | |
28 | where I: IndexedParallelIterator | |
29 | { | |
30 | type Item = (usize, I::Item); | |
31 | ||
32 | fn drive_unindexed<C>(self, consumer: C) -> C::Result | |
33 | where C: UnindexedConsumer<Self::Item> | |
34 | { | |
35 | bridge(self, consumer) | |
36 | } | |
37 | ||
38 | fn opt_len(&self) -> Option<usize> { | |
39 | Some(self.len()) | |
40 | } | |
41 | } | |
42 | ||
43 | impl<I> IndexedParallelIterator for Enumerate<I> | |
44 | where I: IndexedParallelIterator | |
45 | { | |
46 | fn drive<C: Consumer<Self::Item>>(self, consumer: C) -> C::Result { | |
47 | bridge(self, consumer) | |
48 | } | |
49 | ||
50 | fn len(&self) -> usize { | |
51 | self.base.len() | |
52 | } | |
53 | ||
54 | fn with_producer<CB>(self, callback: CB) -> CB::Output | |
55 | where CB: ProducerCallback<Self::Item> | |
56 | { | |
57 | return self.base.with_producer(Callback { callback: callback }); | |
58 | ||
59 | struct Callback<CB> { | |
60 | callback: CB, | |
61 | } | |
62 | ||
63 | impl<I, CB> ProducerCallback<I> for Callback<CB> | |
64 | where CB: ProducerCallback<(usize, I)> | |
65 | { | |
66 | type Output = CB::Output; | |
67 | fn callback<P>(self, base: P) -> CB::Output | |
68 | where P: Producer<Item = I> | |
69 | { | |
70 | let producer = EnumerateProducer { | |
71 | base: base, | |
72 | offset: 0, | |
73 | }; | |
74 | self.callback.callback(producer) | |
75 | } | |
76 | } | |
77 | } | |
78 | } | |
79 | ||
80 | /// //////////////////////////////////////////////////////////////////////// | |
81 | /// Producer implementation | |
82 | ||
83 | struct EnumerateProducer<P> { | |
84 | base: P, | |
85 | offset: usize, | |
86 | } | |
87 | ||
88 | impl<P> Producer for EnumerateProducer<P> | |
89 | where P: Producer | |
90 | { | |
91 | type Item = (usize, P::Item); | |
92 | type IntoIter = iter::Zip<Range<usize>, P::IntoIter>; | |
93 | ||
94 | fn into_iter(self) -> Self::IntoIter { | |
95 | // Enumerate only works for IndexedParallelIterators. Since those | |
96 | // have a max length of usize::MAX, their max index is | |
97 | // usize::MAX - 1, so the range 0..usize::MAX includes all | |
98 | // possible indices. | |
99 | // | |
100 | // However, we should to use a precise end to the range, otherwise | |
101 | // reversing the iterator may have to walk back a long ways before | |
102 | // `Zip::next_back` can produce anything. | |
103 | let base = self.base.into_iter(); | |
104 | let end = self.offset + base.len(); | |
105 | (self.offset..end).zip(base) | |
106 | } | |
107 | ||
108 | fn min_len(&self) -> usize { | |
109 | self.base.min_len() | |
110 | } | |
111 | fn max_len(&self) -> usize { | |
112 | self.base.max_len() | |
113 | } | |
114 | ||
115 | fn split_at(self, index: usize) -> (Self, Self) { | |
116 | let (left, right) = self.base.split_at(index); | |
117 | (EnumerateProducer { | |
118 | base: left, | |
119 | offset: self.offset, | |
120 | }, | |
121 | EnumerateProducer { | |
122 | base: right, | |
123 | offset: self.offset + index, | |
124 | }) | |
125 | } | |
126 | } |