]> git.proxmox.com Git - rustc.git/blob - vendor/rustc-rayon/src/iter/len.rs
New upstream version 1.32.0~beta.2+dfsg1
[rustc.git] / vendor / rustc-rayon / src / iter / len.rs
1 use super::plumbing::*;
2 use super::*;
3 use std::cmp;
4
5 /// `MinLen` is an iterator that imposes a minimum length on iterator splits.
6 /// This struct is created by the [`min_len()`] method on [`IndexedParallelIterator`]
7 ///
8 /// [`min_len()`]: trait.IndexedParallelIterator.html#method.min_len
9 /// [`IndexedParallelIterator`]: trait.IndexedParallelIterator.html
10 #[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
11 #[derive(Debug, Clone)]
12 pub struct MinLen<I: IndexedParallelIterator> {
13 base: I,
14 min: usize,
15 }
16
17 /// Create a new `MinLen` iterator.
18 ///
19 /// NB: a free fn because it is NOT part of the end-user API.
20 pub fn new_min_len<I>(base: I, min: usize) -> MinLen<I>
21 where I: IndexedParallelIterator
22 {
23 MinLen {
24 base: base,
25 min: min,
26 }
27 }
28
29 impl<I> ParallelIterator for MinLen<I>
30 where I: IndexedParallelIterator
31 {
32 type Item = I::Item;
33
34 fn drive_unindexed<C>(self, consumer: C) -> C::Result
35 where C: UnindexedConsumer<Self::Item>
36 {
37 bridge(self, consumer)
38 }
39
40 fn opt_len(&self) -> Option<usize> {
41 Some(self.len())
42 }
43 }
44
45 impl<I> IndexedParallelIterator for MinLen<I>
46 where I: IndexedParallelIterator
47 {
48 fn drive<C: Consumer<Self::Item>>(self, consumer: C) -> C::Result {
49 bridge(self, consumer)
50 }
51
52 fn len(&self) -> usize {
53 self.base.len()
54 }
55
56 fn with_producer<CB>(self, callback: CB) -> CB::Output
57 where CB: ProducerCallback<Self::Item>
58 {
59 return self.base.with_producer(Callback {
60 callback: callback,
61 min: self.min,
62 });
63
64 struct Callback<CB> {
65 callback: CB,
66 min: usize,
67 }
68
69 impl<T, CB> ProducerCallback<T> for Callback<CB>
70 where CB: ProducerCallback<T>
71 {
72 type Output = CB::Output;
73 fn callback<P>(self, base: P) -> CB::Output
74 where P: Producer<Item = T>
75 {
76 let producer = MinLenProducer {
77 base: base,
78 min: self.min,
79 };
80 self.callback.callback(producer)
81 }
82 }
83 }
84 }
85
86 /// ////////////////////////////////////////////////////////////////////////
87 /// `MinLenProducer` implementation
88
89 struct MinLenProducer<P> {
90 base: P,
91 min: usize,
92 }
93
94 impl<P> Producer for MinLenProducer<P>
95 where P: Producer
96 {
97 type Item = P::Item;
98 type IntoIter = P::IntoIter;
99
100 fn into_iter(self) -> Self::IntoIter {
101 self.base.into_iter()
102 }
103
104 fn min_len(&self) -> usize {
105 cmp::max(self.min, self.base.min_len())
106 }
107
108 fn max_len(&self) -> usize {
109 self.base.max_len()
110 }
111
112 fn split_at(self, index: usize) -> (Self, Self) {
113 let (left, right) = self.base.split_at(index);
114 (MinLenProducer {
115 base: left,
116 min: self.min,
117 },
118 MinLenProducer {
119 base: right,
120 min: self.min,
121 })
122 }
123
124 fn fold_with<F>(self, folder: F) -> F
125 where F: Folder<Self::Item>
126 {
127 self.base.fold_with(folder)
128 }
129 }
130
131
132 /// `MaxLen` is an iterator that imposes a maximum length on iterator splits.
133 /// This struct is created by the [`max_len()`] method on [`IndexedParallelIterator`]
134 ///
135 /// [`max_len()`]: trait.IndexedParallelIterator.html#method.max_len
136 /// [`IndexedParallelIterator`]: trait.IndexedParallelIterator.html
137 #[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
138 #[derive(Debug, Clone)]
139 pub struct MaxLen<I: IndexedParallelIterator> {
140 base: I,
141 max: usize,
142 }
143
144 /// Create a new `MaxLen` iterator.
145 ///
146 /// NB: a free fn because it is NOT part of the end-user API.
147 pub fn new_max_len<I>(base: I, max: usize) -> MaxLen<I>
148 where I: IndexedParallelIterator
149 {
150 MaxLen {
151 base: base,
152 max: max,
153 }
154 }
155
156 impl<I> ParallelIterator for MaxLen<I>
157 where I: IndexedParallelIterator
158 {
159 type Item = I::Item;
160
161 fn drive_unindexed<C>(self, consumer: C) -> C::Result
162 where C: UnindexedConsumer<Self::Item>
163 {
164 bridge(self, consumer)
165 }
166
167 fn opt_len(&self) -> Option<usize> {
168 Some(self.len())
169 }
170 }
171
172 impl<I> IndexedParallelIterator for MaxLen<I>
173 where I: IndexedParallelIterator
174 {
175 fn drive<C: Consumer<Self::Item>>(self, consumer: C) -> C::Result {
176 bridge(self, consumer)
177 }
178
179 fn len(&self) -> usize {
180 self.base.len()
181 }
182
183 fn with_producer<CB>(self, callback: CB) -> CB::Output
184 where CB: ProducerCallback<Self::Item>
185 {
186 return self.base.with_producer(Callback {
187 callback: callback,
188 max: self.max,
189 });
190
191 struct Callback<CB> {
192 callback: CB,
193 max: usize,
194 }
195
196 impl<T, CB> ProducerCallback<T> for Callback<CB>
197 where CB: ProducerCallback<T>
198 {
199 type Output = CB::Output;
200 fn callback<P>(self, base: P) -> CB::Output
201 where P: Producer<Item = T>
202 {
203 let producer = MaxLenProducer {
204 base: base,
205 max: self.max,
206 };
207 self.callback.callback(producer)
208 }
209 }
210 }
211 }
212
213 /// ////////////////////////////////////////////////////////////////////////
214 /// `MaxLenProducer` implementation
215
216 struct MaxLenProducer<P> {
217 base: P,
218 max: usize,
219 }
220
221 impl<P> Producer for MaxLenProducer<P>
222 where P: Producer
223 {
224 type Item = P::Item;
225 type IntoIter = P::IntoIter;
226
227 fn into_iter(self) -> Self::IntoIter {
228 self.base.into_iter()
229 }
230
231 fn min_len(&self) -> usize {
232 self.base.min_len()
233 }
234
235 fn max_len(&self) -> usize {
236 cmp::min(self.max, self.base.max_len())
237 }
238
239 fn split_at(self, index: usize) -> (Self, Self) {
240 let (left, right) = self.base.split_at(index);
241 (MaxLenProducer {
242 base: left,
243 max: self.max,
244 },
245 MaxLenProducer {
246 base: right,
247 max: self.max,
248 })
249 }
250
251 fn fold_with<F>(self, folder: F) -> F
252 where F: Folder<Self::Item>
253 {
254 self.base.fold_with(folder)
255 }
256 }