/rust/registry/src/index.crates.io-1949cf8c6b5b557f/rayon-1.11.0/src/iter/unzip.rs
Line | Count | Source |
1 | | use super::plumbing::*; |
2 | | use super::*; |
3 | | |
4 | | /// This trait abstracts the different ways we can "unzip" one parallel |
5 | | /// iterator into two distinct consumers, which we can handle almost |
6 | | /// identically apart from how to process the individual items. |
7 | | trait UnzipOp<T>: Sync + Send { |
8 | | /// The type of item expected by the left consumer. |
9 | | type Left: Send; |
10 | | |
11 | | /// The type of item expected by the right consumer. |
12 | | type Right: Send; |
13 | | |
14 | | /// Consumes one item and feeds it to one or both of the underlying folders. |
15 | | fn consume<FA, FB>(&self, item: T, left: FA, right: FB) -> (FA, FB) |
16 | | where |
17 | | FA: Folder<Self::Left>, |
18 | | FB: Folder<Self::Right>; |
19 | | |
20 | | /// Reports whether this op may support indexed consumers. |
21 | | /// - e.g. true for `unzip` where the item count passed through directly. |
22 | | /// - e.g. false for `partition` where the sorting is not yet known. |
23 | 0 | fn indexable() -> bool { |
24 | 0 | false |
25 | 0 | } |
26 | | } |
27 | | |
28 | | /// Runs an unzip-like operation into default `ParallelExtend` collections. |
29 | 0 | fn execute<I, OP, FromA, FromB>(pi: I, op: OP) -> (FromA, FromB) |
30 | 0 | where |
31 | 0 | I: ParallelIterator, |
32 | 0 | OP: UnzipOp<I::Item>, |
33 | 0 | FromA: Default + Send + ParallelExtend<OP::Left>, |
34 | 0 | FromB: Default + Send + ParallelExtend<OP::Right>, |
35 | | { |
36 | 0 | let mut a = FromA::default(); |
37 | 0 | let mut b = FromB::default(); |
38 | 0 | execute_into(&mut a, &mut b, pi, op); |
39 | 0 | (a, b) |
40 | 0 | } Unexecuted instantiation: rayon::iter::unzip::execute::<rayon::iter::map::Map<rayon::vec::IntoIter<(rav1e::tiling::tiler::TileContextMut<u16>, &mut rav1e::context::cdf_context::CDFContext)>, rav1e::encoder::encode_tile_group<u16>::{closure#0}>, rayon::iter::unzip::Unzip, alloc::vec::Vec<alloc::vec::Vec<u8>>, alloc::vec::Vec<rav1e::stats::EncoderStats>>Unexecuted instantiation: rayon::iter::unzip::execute::<rayon::iter::map::Map<rayon::vec::IntoIter<(rav1e::tiling::tiler::TileContextMut<u8>, &mut rav1e::context::cdf_context::CDFContext)>, rav1e::encoder::encode_tile_group<u8>::{closure#0}>, rayon::iter::unzip::Unzip, alloc::vec::Vec<alloc::vec::Vec<u8>>, alloc::vec::Vec<rav1e::stats::EncoderStats>>Unexecuted instantiation: rayon::iter::unzip::execute::<_, _, _, _> |
41 | | |
42 | | /// Runs an unzip-like operation into `ParallelExtend` collections. |
43 | 0 | fn execute_into<I, OP, FromA, FromB>(a: &mut FromA, b: &mut FromB, pi: I, op: OP) |
44 | 0 | where |
45 | 0 | I: ParallelIterator, |
46 | 0 | OP: UnzipOp<I::Item>, |
47 | 0 | FromA: Send + ParallelExtend<OP::Left>, |
48 | 0 | FromB: Send + ParallelExtend<OP::Right>, |
49 | | { |
50 | | // We have no idea what the consumers will look like for these |
51 | | // collections' `par_extend`, but we can intercept them in our own |
52 | | // `drive_unindexed`. Start with the left side, type `A`: |
53 | 0 | let iter = UnzipA { base: pi, op, b }; |
54 | 0 | a.par_extend(iter); |
55 | 0 | } Unexecuted instantiation: rayon::iter::unzip::execute_into::<rayon::iter::map::Map<rayon::vec::IntoIter<(rav1e::tiling::tiler::TileContextMut<u16>, &mut rav1e::context::cdf_context::CDFContext)>, rav1e::encoder::encode_tile_group<u16>::{closure#0}>, rayon::iter::unzip::Unzip, alloc::vec::Vec<alloc::vec::Vec<u8>>, alloc::vec::Vec<rav1e::stats::EncoderStats>>Unexecuted instantiation: rayon::iter::unzip::execute_into::<rayon::iter::map::Map<rayon::vec::IntoIter<(rav1e::tiling::tiler::TileContextMut<u8>, &mut rav1e::context::cdf_context::CDFContext)>, rav1e::encoder::encode_tile_group<u8>::{closure#0}>, rayon::iter::unzip::Unzip, alloc::vec::Vec<alloc::vec::Vec<u8>>, alloc::vec::Vec<rav1e::stats::EncoderStats>>Unexecuted instantiation: rayon::iter::unzip::execute_into::<_, _, _, _> |
56 | | |
57 | | /// Unzips the items of a parallel iterator into a pair of arbitrary |
58 | | /// `ParallelExtend` containers. |
59 | | /// |
60 | | /// This is called by `ParallelIterator::unzip`. |
61 | 0 | pub(super) fn unzip<I, A, B, FromA, FromB>(pi: I) -> (FromA, FromB) |
62 | 0 | where |
63 | 0 | I: ParallelIterator<Item = (A, B)>, |
64 | 0 | FromA: Default + Send + ParallelExtend<A>, |
65 | 0 | FromB: Default + Send + ParallelExtend<B>, |
66 | 0 | A: Send, |
67 | 0 | B: Send, |
68 | | { |
69 | 0 | execute(pi, Unzip) |
70 | 0 | } Unexecuted instantiation: rayon::iter::unzip::unzip::<rayon::iter::map::Map<rayon::vec::IntoIter<(rav1e::tiling::tiler::TileContextMut<u16>, &mut rav1e::context::cdf_context::CDFContext)>, rav1e::encoder::encode_tile_group<u16>::{closure#0}>, alloc::vec::Vec<u8>, rav1e::stats::EncoderStats, alloc::vec::Vec<alloc::vec::Vec<u8>>, alloc::vec::Vec<rav1e::stats::EncoderStats>>Unexecuted instantiation: rayon::iter::unzip::unzip::<rayon::iter::map::Map<rayon::vec::IntoIter<(rav1e::tiling::tiler::TileContextMut<u8>, &mut rav1e::context::cdf_context::CDFContext)>, rav1e::encoder::encode_tile_group<u8>::{closure#0}>, alloc::vec::Vec<u8>, rav1e::stats::EncoderStats, alloc::vec::Vec<alloc::vec::Vec<u8>>, alloc::vec::Vec<rav1e::stats::EncoderStats>>Unexecuted instantiation: rayon::iter::unzip::unzip::<_, _, _, _, _> |
71 | | |
72 | | /// Unzips an `IndexedParallelIterator` into two arbitrary `Consumer`s. |
73 | | /// |
74 | | /// This is called by `super::collect::unzip_into_vecs`. |
75 | 0 | pub(super) fn unzip_indexed<I, A, B, CA, CB>(pi: I, left: CA, right: CB) -> (CA::Result, CB::Result) |
76 | 0 | where |
77 | 0 | I: IndexedParallelIterator<Item = (A, B)>, |
78 | 0 | CA: Consumer<A>, |
79 | 0 | CB: Consumer<B>, |
80 | 0 | A: Send, |
81 | 0 | B: Send, |
82 | | { |
83 | 0 | let consumer = UnzipConsumer { |
84 | 0 | op: &Unzip, |
85 | 0 | left, |
86 | 0 | right, |
87 | 0 | }; |
88 | 0 | pi.drive(consumer) |
89 | 0 | } |
90 | | |
91 | | /// An `UnzipOp` that splits a tuple directly into the two consumers. |
92 | | struct Unzip; |
93 | | |
94 | | impl<A: Send, B: Send> UnzipOp<(A, B)> for Unzip { |
95 | | type Left = A; |
96 | | type Right = B; |
97 | | |
98 | 0 | fn consume<FA, FB>(&self, item: (A, B), left: FA, right: FB) -> (FA, FB) |
99 | 0 | where |
100 | 0 | FA: Folder<A>, |
101 | 0 | FB: Folder<B>, |
102 | | { |
103 | 0 | (left.consume(item.0), right.consume(item.1)) |
104 | 0 | } Unexecuted instantiation: <rayon::iter::unzip::Unzip as rayon::iter::unzip::UnzipOp<(alloc::vec::Vec<u8>, rav1e::stats::EncoderStats)>>::consume::<rayon::iter::extend::ListVecFolder<alloc::vec::Vec<u8>>, rayon::iter::extend::ListVecFolder<rav1e::stats::EncoderStats>> Unexecuted instantiation: <rayon::iter::unzip::Unzip as rayon::iter::unzip::UnzipOp<(alloc::vec::Vec<u8>, rav1e::stats::EncoderStats)>>::consume::<rayon::iter::extend::ListVecFolder<alloc::vec::Vec<u8>>, rayon::iter::collect::consumer::CollectResult<rav1e::stats::EncoderStats>> Unexecuted instantiation: <rayon::iter::unzip::Unzip as rayon::iter::unzip::UnzipOp<(alloc::vec::Vec<u8>, rav1e::stats::EncoderStats)>>::consume::<rayon::iter::collect::consumer::CollectResult<alloc::vec::Vec<u8>>, rayon::iter::collect::consumer::CollectResult<rav1e::stats::EncoderStats>> Unexecuted instantiation: <rayon::iter::unzip::Unzip as rayon::iter::unzip::UnzipOp<(alloc::vec::Vec<u8>, rav1e::stats::EncoderStats)>>::consume::<rayon::iter::collect::consumer::CollectResult<alloc::vec::Vec<u8>>, rayon::iter::extend::ListVecFolder<rav1e::stats::EncoderStats>> Unexecuted instantiation: <rayon::iter::unzip::Unzip as rayon::iter::unzip::UnzipOp<(_, _)>>::consume::<_, _> |
105 | | |
106 | 0 | fn indexable() -> bool { |
107 | 0 | true |
108 | 0 | } Unexecuted instantiation: <rayon::iter::unzip::Unzip as rayon::iter::unzip::UnzipOp<(alloc::vec::Vec<u8>, rav1e::stats::EncoderStats)>>::indexable Unexecuted instantiation: <rayon::iter::unzip::Unzip as rayon::iter::unzip::UnzipOp<(_, _)>>::indexable |
109 | | } |
110 | | |
111 | | /// Partitions the items of a parallel iterator into a pair of arbitrary |
112 | | /// `ParallelExtend` containers. |
113 | | /// |
114 | | /// This is called by `ParallelIterator::partition`. |
115 | 0 | pub(super) fn partition<I, A, B, P>(pi: I, predicate: P) -> (A, B) |
116 | 0 | where |
117 | 0 | I: ParallelIterator, |
118 | 0 | A: Default + Send + ParallelExtend<I::Item>, |
119 | 0 | B: Default + Send + ParallelExtend<I::Item>, |
120 | 0 | P: Fn(&I::Item) -> bool + Sync + Send, |
121 | | { |
122 | 0 | execute(pi, Partition { predicate }) |
123 | 0 | } |
124 | | |
125 | | /// An `UnzipOp` that routes items depending on a predicate function. |
126 | | struct Partition<P> { |
127 | | predicate: P, |
128 | | } |
129 | | |
130 | | impl<P, T> UnzipOp<T> for Partition<P> |
131 | | where |
132 | | P: Fn(&T) -> bool + Sync + Send, |
133 | | T: Send, |
134 | | { |
135 | | type Left = T; |
136 | | type Right = T; |
137 | | |
138 | 0 | fn consume<FA, FB>(&self, item: T, left: FA, right: FB) -> (FA, FB) |
139 | 0 | where |
140 | 0 | FA: Folder<T>, |
141 | 0 | FB: Folder<T>, |
142 | | { |
143 | 0 | if (self.predicate)(&item) { |
144 | 0 | (left.consume(item), right) |
145 | | } else { |
146 | 0 | (left, right.consume(item)) |
147 | | } |
148 | 0 | } |
149 | | } |
150 | | |
151 | | /// Partitions and maps the items of a parallel iterator into a pair of |
152 | | /// arbitrary `ParallelExtend` containers. |
153 | | /// |
154 | | /// This called by `ParallelIterator::partition_map`. |
155 | 0 | pub(super) fn partition_map<I, A, B, P, L, R>(pi: I, predicate: P) -> (A, B) |
156 | 0 | where |
157 | 0 | I: ParallelIterator, |
158 | 0 | A: Default + Send + ParallelExtend<L>, |
159 | 0 | B: Default + Send + ParallelExtend<R>, |
160 | 0 | P: Fn(I::Item) -> Either<L, R> + Sync + Send, |
161 | 0 | L: Send, |
162 | 0 | R: Send, |
163 | | { |
164 | 0 | execute(pi, PartitionMap { predicate }) |
165 | 0 | } |
166 | | |
167 | | /// An `UnzipOp` that routes items depending on how they are mapped `Either`. |
168 | | struct PartitionMap<P> { |
169 | | predicate: P, |
170 | | } |
171 | | |
172 | | impl<P, L, R, T> UnzipOp<T> for PartitionMap<P> |
173 | | where |
174 | | P: Fn(T) -> Either<L, R> + Sync + Send, |
175 | | L: Send, |
176 | | R: Send, |
177 | | { |
178 | | type Left = L; |
179 | | type Right = R; |
180 | | |
181 | 0 | fn consume<FA, FB>(&self, item: T, left: FA, right: FB) -> (FA, FB) |
182 | 0 | where |
183 | 0 | FA: Folder<L>, |
184 | 0 | FB: Folder<R>, |
185 | | { |
186 | 0 | match (self.predicate)(item) { |
187 | 0 | Either::Left(item) => (left.consume(item), right), |
188 | 0 | Either::Right(item) => (left, right.consume(item)), |
189 | | } |
190 | 0 | } |
191 | | } |
192 | | |
193 | | /// A fake iterator to intercept the `Consumer` for type `A`. |
194 | | struct UnzipA<'b, I, OP, FromB> { |
195 | | base: I, |
196 | | op: OP, |
197 | | b: &'b mut FromB, |
198 | | } |
199 | | |
200 | | impl<'b, I, OP, FromB> ParallelIterator for UnzipA<'b, I, OP, FromB> |
201 | | where |
202 | | I: ParallelIterator, |
203 | | OP: UnzipOp<I::Item>, |
204 | | FromB: Send + ParallelExtend<OP::Right>, |
205 | | { |
206 | | type Item = OP::Left; |
207 | | |
208 | 0 | fn drive_unindexed<C>(self, consumer: C) -> C::Result |
209 | 0 | where |
210 | 0 | C: UnindexedConsumer<Self::Item>, |
211 | | { |
212 | 0 | let mut result = None; |
213 | 0 | { |
214 | 0 | // Now it's time to find the consumer for type `B` |
215 | 0 | let iter = UnzipB { |
216 | 0 | base: self.base, |
217 | 0 | op: self.op, |
218 | 0 | left_consumer: consumer, |
219 | 0 | left_result: &mut result, |
220 | 0 | }; |
221 | 0 | self.b.par_extend(iter); |
222 | 0 | } |
223 | | // NB: If for some reason `b.par_extend` doesn't actually drive the |
224 | | // iterator, then we won't have a result for the left side to return |
225 | | // at all. We can't fake an arbitrary consumer's result, so panic. |
226 | 0 | result.expect("unzip consumers didn't execute!") |
227 | 0 | } Unexecuted instantiation: <rayon::iter::unzip::UnzipA<rayon::iter::map::Map<rayon::vec::IntoIter<(rav1e::tiling::tiler::TileContextMut<u16>, &mut rav1e::context::cdf_context::CDFContext)>, rav1e::encoder::encode_tile_group<u16>::{closure#0}>, rayon::iter::unzip::Unzip, alloc::vec::Vec<rav1e::stats::EncoderStats>> as rayon::iter::ParallelIterator>::drive_unindexed::<rayon::iter::collect::consumer::CollectConsumer<alloc::vec::Vec<u8>>>Unexecuted instantiation: <rayon::iter::unzip::UnzipA<rayon::iter::map::Map<rayon::vec::IntoIter<(rav1e::tiling::tiler::TileContextMut<u16>, &mut rav1e::context::cdf_context::CDFContext)>, rav1e::encoder::encode_tile_group<u16>::{closure#0}>, rayon::iter::unzip::Unzip, alloc::vec::Vec<rav1e::stats::EncoderStats>> as rayon::iter::ParallelIterator>::drive_unindexed::<rayon::iter::extend::ListVecConsumer>Unexecuted instantiation: <rayon::iter::unzip::UnzipA<rayon::iter::map::Map<rayon::vec::IntoIter<(rav1e::tiling::tiler::TileContextMut<u8>, &mut rav1e::context::cdf_context::CDFContext)>, rav1e::encoder::encode_tile_group<u8>::{closure#0}>, rayon::iter::unzip::Unzip, alloc::vec::Vec<rav1e::stats::EncoderStats>> as rayon::iter::ParallelIterator>::drive_unindexed::<rayon::iter::collect::consumer::CollectConsumer<alloc::vec::Vec<u8>>>Unexecuted instantiation: <rayon::iter::unzip::UnzipA<rayon::iter::map::Map<rayon::vec::IntoIter<(rav1e::tiling::tiler::TileContextMut<u8>, &mut rav1e::context::cdf_context::CDFContext)>, rav1e::encoder::encode_tile_group<u8>::{closure#0}>, rayon::iter::unzip::Unzip, alloc::vec::Vec<rav1e::stats::EncoderStats>> as rayon::iter::ParallelIterator>::drive_unindexed::<rayon::iter::extend::ListVecConsumer>Unexecuted instantiation: <rayon::iter::unzip::UnzipA<_, _, _> as rayon::iter::ParallelIterator>::drive_unindexed::<_> |
228 | | |
229 | 0 | fn opt_len(&self) -> Option<usize> { |
230 | 0 | if OP::indexable() { |
231 | 0 | self.base.opt_len() |
232 | | } else { |
233 | 0 | None |
234 | | } |
235 | 0 | } Unexecuted instantiation: <rayon::iter::unzip::UnzipA<rayon::iter::map::Map<rayon::vec::IntoIter<(rav1e::tiling::tiler::TileContextMut<u16>, &mut rav1e::context::cdf_context::CDFContext)>, rav1e::encoder::encode_tile_group<u16>::{closure#0}>, rayon::iter::unzip::Unzip, alloc::vec::Vec<rav1e::stats::EncoderStats>> as rayon::iter::ParallelIterator>::opt_lenUnexecuted instantiation: <rayon::iter::unzip::UnzipA<rayon::iter::map::Map<rayon::vec::IntoIter<(rav1e::tiling::tiler::TileContextMut<u8>, &mut rav1e::context::cdf_context::CDFContext)>, rav1e::encoder::encode_tile_group<u8>::{closure#0}>, rayon::iter::unzip::Unzip, alloc::vec::Vec<rav1e::stats::EncoderStats>> as rayon::iter::ParallelIterator>::opt_lenUnexecuted instantiation: <rayon::iter::unzip::UnzipA<_, _, _> as rayon::iter::ParallelIterator>::opt_len |
236 | | } |
237 | | |
238 | | /// A fake iterator to intercept the `Consumer` for type `B`. |
239 | | struct UnzipB<'r, I, OP, CA> |
240 | | where |
241 | | I: ParallelIterator, |
242 | | OP: UnzipOp<I::Item>, |
243 | | CA: UnindexedConsumer<OP::Left>, |
244 | | { |
245 | | base: I, |
246 | | op: OP, |
247 | | left_consumer: CA, |
248 | | left_result: &'r mut Option<CA::Result>, |
249 | | } |
250 | | |
251 | | impl<'r, I, OP, CA> ParallelIterator for UnzipB<'r, I, OP, CA> |
252 | | where |
253 | | I: ParallelIterator, |
254 | | OP: UnzipOp<I::Item>, |
255 | | CA: UnindexedConsumer<OP::Left>, |
256 | | { |
257 | | type Item = OP::Right; |
258 | | |
259 | 0 | fn drive_unindexed<C>(self, consumer: C) -> C::Result |
260 | 0 | where |
261 | 0 | C: UnindexedConsumer<Self::Item>, |
262 | | { |
263 | | // Now that we have two consumers, we can unzip the real iterator. |
264 | 0 | let consumer = UnzipConsumer { |
265 | 0 | op: &self.op, |
266 | 0 | left: self.left_consumer, |
267 | 0 | right: consumer, |
268 | 0 | }; |
269 | | |
270 | 0 | let result = self.base.drive_unindexed(consumer); |
271 | 0 | *self.left_result = Some(result.0); |
272 | 0 | result.1 |
273 | 0 | } Unexecuted instantiation: <rayon::iter::unzip::UnzipB<rayon::iter::map::Map<rayon::vec::IntoIter<(rav1e::tiling::tiler::TileContextMut<u16>, &mut rav1e::context::cdf_context::CDFContext)>, rav1e::encoder::encode_tile_group<u16>::{closure#0}>, rayon::iter::unzip::Unzip, rayon::iter::collect::consumer::CollectConsumer<alloc::vec::Vec<u8>>> as rayon::iter::ParallelIterator>::drive_unindexed::<rayon::iter::collect::consumer::CollectConsumer<rav1e::stats::EncoderStats>>Unexecuted instantiation: <rayon::iter::unzip::UnzipB<rayon::iter::map::Map<rayon::vec::IntoIter<(rav1e::tiling::tiler::TileContextMut<u16>, &mut rav1e::context::cdf_context::CDFContext)>, rav1e::encoder::encode_tile_group<u16>::{closure#0}>, rayon::iter::unzip::Unzip, rayon::iter::collect::consumer::CollectConsumer<alloc::vec::Vec<u8>>> as rayon::iter::ParallelIterator>::drive_unindexed::<rayon::iter::extend::ListVecConsumer>Unexecuted instantiation: <rayon::iter::unzip::UnzipB<rayon::iter::map::Map<rayon::vec::IntoIter<(rav1e::tiling::tiler::TileContextMut<u16>, &mut rav1e::context::cdf_context::CDFContext)>, rav1e::encoder::encode_tile_group<u16>::{closure#0}>, rayon::iter::unzip::Unzip, rayon::iter::extend::ListVecConsumer> as rayon::iter::ParallelIterator>::drive_unindexed::<rayon::iter::extend::ListVecConsumer>Unexecuted instantiation: <rayon::iter::unzip::UnzipB<rayon::iter::map::Map<rayon::vec::IntoIter<(rav1e::tiling::tiler::TileContextMut<u16>, &mut rav1e::context::cdf_context::CDFContext)>, rav1e::encoder::encode_tile_group<u16>::{closure#0}>, rayon::iter::unzip::Unzip, rayon::iter::extend::ListVecConsumer> as rayon::iter::ParallelIterator>::drive_unindexed::<rayon::iter::collect::consumer::CollectConsumer<rav1e::stats::EncoderStats>>Unexecuted instantiation: <rayon::iter::unzip::UnzipB<rayon::iter::map::Map<rayon::vec::IntoIter<(rav1e::tiling::tiler::TileContextMut<u8>, &mut rav1e::context::cdf_context::CDFContext)>, rav1e::encoder::encode_tile_group<u8>::{closure#0}>, rayon::iter::unzip::Unzip, rayon::iter::collect::consumer::CollectConsumer<alloc::vec::Vec<u8>>> as rayon::iter::ParallelIterator>::drive_unindexed::<rayon::iter::collect::consumer::CollectConsumer<rav1e::stats::EncoderStats>>Unexecuted instantiation: <rayon::iter::unzip::UnzipB<rayon::iter::map::Map<rayon::vec::IntoIter<(rav1e::tiling::tiler::TileContextMut<u8>, &mut rav1e::context::cdf_context::CDFContext)>, rav1e::encoder::encode_tile_group<u8>::{closure#0}>, rayon::iter::unzip::Unzip, rayon::iter::collect::consumer::CollectConsumer<alloc::vec::Vec<u8>>> as rayon::iter::ParallelIterator>::drive_unindexed::<rayon::iter::extend::ListVecConsumer>Unexecuted instantiation: <rayon::iter::unzip::UnzipB<rayon::iter::map::Map<rayon::vec::IntoIter<(rav1e::tiling::tiler::TileContextMut<u8>, &mut rav1e::context::cdf_context::CDFContext)>, rav1e::encoder::encode_tile_group<u8>::{closure#0}>, rayon::iter::unzip::Unzip, rayon::iter::extend::ListVecConsumer> as rayon::iter::ParallelIterator>::drive_unindexed::<rayon::iter::extend::ListVecConsumer>Unexecuted instantiation: <rayon::iter::unzip::UnzipB<rayon::iter::map::Map<rayon::vec::IntoIter<(rav1e::tiling::tiler::TileContextMut<u8>, &mut rav1e::context::cdf_context::CDFContext)>, rav1e::encoder::encode_tile_group<u8>::{closure#0}>, rayon::iter::unzip::Unzip, rayon::iter::extend::ListVecConsumer> as rayon::iter::ParallelIterator>::drive_unindexed::<rayon::iter::collect::consumer::CollectConsumer<rav1e::stats::EncoderStats>>Unexecuted instantiation: <rayon::iter::unzip::UnzipB<_, _, _> as rayon::iter::ParallelIterator>::drive_unindexed::<_> |
274 | | |
275 | 0 | fn opt_len(&self) -> Option<usize> { |
276 | 0 | if OP::indexable() { |
277 | 0 | self.base.opt_len() |
278 | | } else { |
279 | 0 | None |
280 | | } |
281 | 0 | } Unexecuted instantiation: <rayon::iter::unzip::UnzipB<rayon::iter::map::Map<rayon::vec::IntoIter<(rav1e::tiling::tiler::TileContextMut<u16>, &mut rav1e::context::cdf_context::CDFContext)>, rav1e::encoder::encode_tile_group<u16>::{closure#0}>, rayon::iter::unzip::Unzip, rayon::iter::collect::consumer::CollectConsumer<alloc::vec::Vec<u8>>> as rayon::iter::ParallelIterator>::opt_lenUnexecuted instantiation: <rayon::iter::unzip::UnzipB<rayon::iter::map::Map<rayon::vec::IntoIter<(rav1e::tiling::tiler::TileContextMut<u16>, &mut rav1e::context::cdf_context::CDFContext)>, rav1e::encoder::encode_tile_group<u16>::{closure#0}>, rayon::iter::unzip::Unzip, rayon::iter::extend::ListVecConsumer> as rayon::iter::ParallelIterator>::opt_lenUnexecuted instantiation: <rayon::iter::unzip::UnzipB<rayon::iter::map::Map<rayon::vec::IntoIter<(rav1e::tiling::tiler::TileContextMut<u8>, &mut rav1e::context::cdf_context::CDFContext)>, rav1e::encoder::encode_tile_group<u8>::{closure#0}>, rayon::iter::unzip::Unzip, rayon::iter::collect::consumer::CollectConsumer<alloc::vec::Vec<u8>>> as rayon::iter::ParallelIterator>::opt_lenUnexecuted instantiation: <rayon::iter::unzip::UnzipB<rayon::iter::map::Map<rayon::vec::IntoIter<(rav1e::tiling::tiler::TileContextMut<u8>, &mut rav1e::context::cdf_context::CDFContext)>, rav1e::encoder::encode_tile_group<u8>::{closure#0}>, rayon::iter::unzip::Unzip, rayon::iter::extend::ListVecConsumer> as rayon::iter::ParallelIterator>::opt_lenUnexecuted instantiation: <rayon::iter::unzip::UnzipB<_, _, _> as rayon::iter::ParallelIterator>::opt_len |
282 | | } |
283 | | |
284 | | /// `Consumer` that unzips into two other `Consumer`s |
285 | | struct UnzipConsumer<'a, OP, CA, CB> { |
286 | | op: &'a OP, |
287 | | left: CA, |
288 | | right: CB, |
289 | | } |
290 | | |
291 | | impl<'a, T, OP, CA, CB> Consumer<T> for UnzipConsumer<'a, OP, CA, CB> |
292 | | where |
293 | | OP: UnzipOp<T>, |
294 | | CA: Consumer<OP::Left>, |
295 | | CB: Consumer<OP::Right>, |
296 | | { |
297 | | type Folder = UnzipFolder<'a, OP, CA::Folder, CB::Folder>; |
298 | | type Reducer = UnzipReducer<CA::Reducer, CB::Reducer>; |
299 | | type Result = (CA::Result, CB::Result); |
300 | | |
301 | 0 | fn split_at(self, index: usize) -> (Self, Self, Self::Reducer) { |
302 | 0 | let (left1, left2, left_reducer) = self.left.split_at(index); |
303 | 0 | let (right1, right2, right_reducer) = self.right.split_at(index); |
304 | | |
305 | 0 | ( |
306 | 0 | UnzipConsumer { |
307 | 0 | op: self.op, |
308 | 0 | left: left1, |
309 | 0 | right: right1, |
310 | 0 | }, |
311 | 0 | UnzipConsumer { |
312 | 0 | op: self.op, |
313 | 0 | left: left2, |
314 | 0 | right: right2, |
315 | 0 | }, |
316 | 0 | UnzipReducer { |
317 | 0 | left: left_reducer, |
318 | 0 | right: right_reducer, |
319 | 0 | }, |
320 | 0 | ) |
321 | 0 | } Unexecuted instantiation: <rayon::iter::unzip::UnzipConsumer<rayon::iter::unzip::Unzip, rayon::iter::collect::consumer::CollectConsumer<alloc::vec::Vec<u8>>, rayon::iter::collect::consumer::CollectConsumer<rav1e::stats::EncoderStats>> as rayon::iter::plumbing::Consumer<(alloc::vec::Vec<u8>, rav1e::stats::EncoderStats)>>::split_at Unexecuted instantiation: <rayon::iter::unzip::UnzipConsumer<rayon::iter::unzip::Unzip, rayon::iter::collect::consumer::CollectConsumer<alloc::vec::Vec<u8>>, rayon::iter::extend::ListVecConsumer> as rayon::iter::plumbing::Consumer<(alloc::vec::Vec<u8>, rav1e::stats::EncoderStats)>>::split_at Unexecuted instantiation: <rayon::iter::unzip::UnzipConsumer<rayon::iter::unzip::Unzip, rayon::iter::extend::ListVecConsumer, rayon::iter::extend::ListVecConsumer> as rayon::iter::plumbing::Consumer<(alloc::vec::Vec<u8>, rav1e::stats::EncoderStats)>>::split_at Unexecuted instantiation: <rayon::iter::unzip::UnzipConsumer<rayon::iter::unzip::Unzip, rayon::iter::extend::ListVecConsumer, rayon::iter::collect::consumer::CollectConsumer<rav1e::stats::EncoderStats>> as rayon::iter::plumbing::Consumer<(alloc::vec::Vec<u8>, rav1e::stats::EncoderStats)>>::split_at Unexecuted instantiation: <rayon::iter::unzip::UnzipConsumer<_, _, _> as rayon::iter::plumbing::Consumer<_>>::split_at |
322 | | |
323 | 0 | fn into_folder(self) -> Self::Folder { |
324 | 0 | UnzipFolder { |
325 | 0 | op: self.op, |
326 | 0 | left: self.left.into_folder(), |
327 | 0 | right: self.right.into_folder(), |
328 | 0 | } |
329 | 0 | } Unexecuted instantiation: <rayon::iter::unzip::UnzipConsumer<rayon::iter::unzip::Unzip, rayon::iter::collect::consumer::CollectConsumer<alloc::vec::Vec<u8>>, rayon::iter::collect::consumer::CollectConsumer<rav1e::stats::EncoderStats>> as rayon::iter::plumbing::Consumer<(alloc::vec::Vec<u8>, rav1e::stats::EncoderStats)>>::into_folder Unexecuted instantiation: <rayon::iter::unzip::UnzipConsumer<rayon::iter::unzip::Unzip, rayon::iter::collect::consumer::CollectConsumer<alloc::vec::Vec<u8>>, rayon::iter::extend::ListVecConsumer> as rayon::iter::plumbing::Consumer<(alloc::vec::Vec<u8>, rav1e::stats::EncoderStats)>>::into_folder Unexecuted instantiation: <rayon::iter::unzip::UnzipConsumer<rayon::iter::unzip::Unzip, rayon::iter::extend::ListVecConsumer, rayon::iter::extend::ListVecConsumer> as rayon::iter::plumbing::Consumer<(alloc::vec::Vec<u8>, rav1e::stats::EncoderStats)>>::into_folder Unexecuted instantiation: <rayon::iter::unzip::UnzipConsumer<rayon::iter::unzip::Unzip, rayon::iter::extend::ListVecConsumer, rayon::iter::collect::consumer::CollectConsumer<rav1e::stats::EncoderStats>> as rayon::iter::plumbing::Consumer<(alloc::vec::Vec<u8>, rav1e::stats::EncoderStats)>>::into_folder Unexecuted instantiation: <rayon::iter::unzip::UnzipConsumer<_, _, _> as rayon::iter::plumbing::Consumer<_>>::into_folder |
330 | | |
331 | 0 | fn full(&self) -> bool { |
332 | | // don't stop until everyone is full |
333 | 0 | self.left.full() && self.right.full() |
334 | 0 | } Unexecuted instantiation: <rayon::iter::unzip::UnzipConsumer<rayon::iter::unzip::Unzip, rayon::iter::collect::consumer::CollectConsumer<alloc::vec::Vec<u8>>, rayon::iter::collect::consumer::CollectConsumer<rav1e::stats::EncoderStats>> as rayon::iter::plumbing::Consumer<(alloc::vec::Vec<u8>, rav1e::stats::EncoderStats)>>::full Unexecuted instantiation: <rayon::iter::unzip::UnzipConsumer<rayon::iter::unzip::Unzip, rayon::iter::collect::consumer::CollectConsumer<alloc::vec::Vec<u8>>, rayon::iter::extend::ListVecConsumer> as rayon::iter::plumbing::Consumer<(alloc::vec::Vec<u8>, rav1e::stats::EncoderStats)>>::full Unexecuted instantiation: <rayon::iter::unzip::UnzipConsumer<rayon::iter::unzip::Unzip, rayon::iter::extend::ListVecConsumer, rayon::iter::extend::ListVecConsumer> as rayon::iter::plumbing::Consumer<(alloc::vec::Vec<u8>, rav1e::stats::EncoderStats)>>::full Unexecuted instantiation: <rayon::iter::unzip::UnzipConsumer<rayon::iter::unzip::Unzip, rayon::iter::extend::ListVecConsumer, rayon::iter::collect::consumer::CollectConsumer<rav1e::stats::EncoderStats>> as rayon::iter::plumbing::Consumer<(alloc::vec::Vec<u8>, rav1e::stats::EncoderStats)>>::full Unexecuted instantiation: <rayon::iter::unzip::UnzipConsumer<_, _, _> as rayon::iter::plumbing::Consumer<_>>::full |
335 | | } |
336 | | |
337 | | impl<'a, T, OP, CA, CB> UnindexedConsumer<T> for UnzipConsumer<'a, OP, CA, CB> |
338 | | where |
339 | | OP: UnzipOp<T>, |
340 | | CA: UnindexedConsumer<OP::Left>, |
341 | | CB: UnindexedConsumer<OP::Right>, |
342 | | { |
343 | 0 | fn split_off_left(&self) -> Self { |
344 | 0 | UnzipConsumer { |
345 | 0 | op: self.op, |
346 | 0 | left: self.left.split_off_left(), |
347 | 0 | right: self.right.split_off_left(), |
348 | 0 | } |
349 | 0 | } |
350 | | |
351 | 0 | fn to_reducer(&self) -> Self::Reducer { |
352 | 0 | UnzipReducer { |
353 | 0 | left: self.left.to_reducer(), |
354 | 0 | right: self.right.to_reducer(), |
355 | 0 | } |
356 | 0 | } |
357 | | } |
358 | | |
359 | | /// `Folder` that unzips into two other `Folder`s |
360 | | struct UnzipFolder<'a, OP, FA, FB> { |
361 | | op: &'a OP, |
362 | | left: FA, |
363 | | right: FB, |
364 | | } |
365 | | |
366 | | impl<'a, T, OP, FA, FB> Folder<T> for UnzipFolder<'a, OP, FA, FB> |
367 | | where |
368 | | OP: UnzipOp<T>, |
369 | | FA: Folder<OP::Left>, |
370 | | FB: Folder<OP::Right>, |
371 | | { |
372 | | type Result = (FA::Result, FB::Result); |
373 | | |
374 | 0 | fn consume(self, item: T) -> Self { |
375 | 0 | let (left, right) = self.op.consume(item, self.left, self.right); |
376 | 0 | UnzipFolder { |
377 | 0 | op: self.op, |
378 | 0 | left, |
379 | 0 | right, |
380 | 0 | } |
381 | 0 | } Unexecuted instantiation: <rayon::iter::unzip::UnzipFolder<rayon::iter::unzip::Unzip, rayon::iter::extend::ListVecFolder<alloc::vec::Vec<u8>>, rayon::iter::extend::ListVecFolder<rav1e::stats::EncoderStats>> as rayon::iter::plumbing::Folder<(alloc::vec::Vec<u8>, rav1e::stats::EncoderStats)>>::consume Unexecuted instantiation: <rayon::iter::unzip::UnzipFolder<rayon::iter::unzip::Unzip, rayon::iter::extend::ListVecFolder<alloc::vec::Vec<u8>>, rayon::iter::collect::consumer::CollectResult<rav1e::stats::EncoderStats>> as rayon::iter::plumbing::Folder<(alloc::vec::Vec<u8>, rav1e::stats::EncoderStats)>>::consume Unexecuted instantiation: <rayon::iter::unzip::UnzipFolder<rayon::iter::unzip::Unzip, rayon::iter::collect::consumer::CollectResult<alloc::vec::Vec<u8>>, rayon::iter::collect::consumer::CollectResult<rav1e::stats::EncoderStats>> as rayon::iter::plumbing::Folder<(alloc::vec::Vec<u8>, rav1e::stats::EncoderStats)>>::consume Unexecuted instantiation: <rayon::iter::unzip::UnzipFolder<rayon::iter::unzip::Unzip, rayon::iter::collect::consumer::CollectResult<alloc::vec::Vec<u8>>, rayon::iter::extend::ListVecFolder<rav1e::stats::EncoderStats>> as rayon::iter::plumbing::Folder<(alloc::vec::Vec<u8>, rav1e::stats::EncoderStats)>>::consume Unexecuted instantiation: <rayon::iter::unzip::UnzipFolder<_, _, _> as rayon::iter::plumbing::Folder<_>>::consume |
382 | | |
383 | 0 | fn complete(self) -> Self::Result { |
384 | 0 | (self.left.complete(), self.right.complete()) |
385 | 0 | } Unexecuted instantiation: <rayon::iter::unzip::UnzipFolder<rayon::iter::unzip::Unzip, rayon::iter::extend::ListVecFolder<alloc::vec::Vec<u8>>, rayon::iter::extend::ListVecFolder<rav1e::stats::EncoderStats>> as rayon::iter::plumbing::Folder<(alloc::vec::Vec<u8>, rav1e::stats::EncoderStats)>>::complete Unexecuted instantiation: <rayon::iter::unzip::UnzipFolder<rayon::iter::unzip::Unzip, rayon::iter::extend::ListVecFolder<alloc::vec::Vec<u8>>, rayon::iter::collect::consumer::CollectResult<rav1e::stats::EncoderStats>> as rayon::iter::plumbing::Folder<(alloc::vec::Vec<u8>, rav1e::stats::EncoderStats)>>::complete Unexecuted instantiation: <rayon::iter::unzip::UnzipFolder<rayon::iter::unzip::Unzip, rayon::iter::collect::consumer::CollectResult<alloc::vec::Vec<u8>>, rayon::iter::collect::consumer::CollectResult<rav1e::stats::EncoderStats>> as rayon::iter::plumbing::Folder<(alloc::vec::Vec<u8>, rav1e::stats::EncoderStats)>>::complete Unexecuted instantiation: <rayon::iter::unzip::UnzipFolder<rayon::iter::unzip::Unzip, rayon::iter::collect::consumer::CollectResult<alloc::vec::Vec<u8>>, rayon::iter::extend::ListVecFolder<rav1e::stats::EncoderStats>> as rayon::iter::plumbing::Folder<(alloc::vec::Vec<u8>, rav1e::stats::EncoderStats)>>::complete Unexecuted instantiation: <rayon::iter::unzip::UnzipFolder<_, _, _> as rayon::iter::plumbing::Folder<_>>::complete |
386 | | |
387 | 0 | fn full(&self) -> bool { |
388 | | // don't stop until everyone is full |
389 | 0 | self.left.full() && self.right.full() |
390 | 0 | } Unexecuted instantiation: <rayon::iter::unzip::UnzipFolder<rayon::iter::unzip::Unzip, rayon::iter::extend::ListVecFolder<alloc::vec::Vec<u8>>, rayon::iter::extend::ListVecFolder<rav1e::stats::EncoderStats>> as rayon::iter::plumbing::Folder<(alloc::vec::Vec<u8>, rav1e::stats::EncoderStats)>>::full Unexecuted instantiation: <rayon::iter::unzip::UnzipFolder<rayon::iter::unzip::Unzip, rayon::iter::extend::ListVecFolder<alloc::vec::Vec<u8>>, rayon::iter::collect::consumer::CollectResult<rav1e::stats::EncoderStats>> as rayon::iter::plumbing::Folder<(alloc::vec::Vec<u8>, rav1e::stats::EncoderStats)>>::full Unexecuted instantiation: <rayon::iter::unzip::UnzipFolder<rayon::iter::unzip::Unzip, rayon::iter::collect::consumer::CollectResult<alloc::vec::Vec<u8>>, rayon::iter::collect::consumer::CollectResult<rav1e::stats::EncoderStats>> as rayon::iter::plumbing::Folder<(alloc::vec::Vec<u8>, rav1e::stats::EncoderStats)>>::full Unexecuted instantiation: <rayon::iter::unzip::UnzipFolder<rayon::iter::unzip::Unzip, rayon::iter::collect::consumer::CollectResult<alloc::vec::Vec<u8>>, rayon::iter::extend::ListVecFolder<rav1e::stats::EncoderStats>> as rayon::iter::plumbing::Folder<(alloc::vec::Vec<u8>, rav1e::stats::EncoderStats)>>::full Unexecuted instantiation: <rayon::iter::unzip::UnzipFolder<_, _, _> as rayon::iter::plumbing::Folder<_>>::full |
391 | | } |
392 | | |
393 | | /// `Reducer` that unzips into two other `Reducer`s |
394 | | struct UnzipReducer<RA, RB> { |
395 | | left: RA, |
396 | | right: RB, |
397 | | } |
398 | | |
399 | | impl<A, B, RA, RB> Reducer<(A, B)> for UnzipReducer<RA, RB> |
400 | | where |
401 | | RA: Reducer<A>, |
402 | | RB: Reducer<B>, |
403 | | { |
404 | 0 | fn reduce(self, left: (A, B), right: (A, B)) -> (A, B) { |
405 | 0 | ( |
406 | 0 | self.left.reduce(left.0, right.0), |
407 | 0 | self.right.reduce(left.1, right.1), |
408 | 0 | ) |
409 | 0 | } Unexecuted instantiation: <rayon::iter::unzip::UnzipReducer<rayon::iter::extend::ListReducer, rayon::iter::extend::ListReducer> as rayon::iter::plumbing::Reducer<(alloc::collections::linked_list::LinkedList<alloc::vec::Vec<alloc::vec::Vec<u8>>>, alloc::collections::linked_list::LinkedList<alloc::vec::Vec<rav1e::stats::EncoderStats>>)>>::reduce Unexecuted instantiation: <rayon::iter::unzip::UnzipReducer<rayon::iter::extend::ListReducer, rayon::iter::collect::consumer::CollectReducer> as rayon::iter::plumbing::Reducer<(alloc::collections::linked_list::LinkedList<alloc::vec::Vec<alloc::vec::Vec<u8>>>, rayon::iter::collect::consumer::CollectResult<rav1e::stats::EncoderStats>)>>::reduce Unexecuted instantiation: <rayon::iter::unzip::UnzipReducer<rayon::iter::collect::consumer::CollectReducer, rayon::iter::collect::consumer::CollectReducer> as rayon::iter::plumbing::Reducer<(rayon::iter::collect::consumer::CollectResult<alloc::vec::Vec<u8>>, rayon::iter::collect::consumer::CollectResult<rav1e::stats::EncoderStats>)>>::reduce Unexecuted instantiation: <rayon::iter::unzip::UnzipReducer<rayon::iter::collect::consumer::CollectReducer, rayon::iter::extend::ListReducer> as rayon::iter::plumbing::Reducer<(rayon::iter::collect::consumer::CollectResult<alloc::vec::Vec<u8>>, alloc::collections::linked_list::LinkedList<alloc::vec::Vec<rav1e::stats::EncoderStats>>)>>::reduce Unexecuted instantiation: <rayon::iter::unzip::UnzipReducer<_, _> as rayon::iter::plumbing::Reducer<(_, _)>>::reduce |
410 | | } |
411 | | |
412 | | impl<A, B, FromA, FromB> ParallelExtend<(A, B)> for (FromA, FromB) |
413 | | where |
414 | | A: Send, |
415 | | B: Send, |
416 | | FromA: Send + ParallelExtend<A>, |
417 | | FromB: Send + ParallelExtend<B>, |
418 | | { |
419 | 0 | fn par_extend<I>(&mut self, pi: I) |
420 | 0 | where |
421 | 0 | I: IntoParallelIterator<Item = (A, B)>, |
422 | | { |
423 | 0 | execute_into(&mut self.0, &mut self.1, pi.into_par_iter(), Unzip); |
424 | 0 | } |
425 | | } |
426 | | |
427 | | impl<L, R, A, B> ParallelExtend<Either<L, R>> for (A, B) |
428 | | where |
429 | | L: Send, |
430 | | R: Send, |
431 | | A: Send + ParallelExtend<L>, |
432 | | B: Send + ParallelExtend<R>, |
433 | | { |
434 | 0 | fn par_extend<I>(&mut self, pi: I) |
435 | 0 | where |
436 | 0 | I: IntoParallelIterator<Item = Either<L, R>>, |
437 | | { |
438 | 0 | execute_into(&mut self.0, &mut self.1, pi.into_par_iter(), UnEither); |
439 | 0 | } |
440 | | } |
441 | | |
442 | | /// An `UnzipOp` that routes items depending on their `Either` variant. |
443 | | struct UnEither; |
444 | | |
445 | | impl<L, R> UnzipOp<Either<L, R>> for UnEither |
446 | | where |
447 | | L: Send, |
448 | | R: Send, |
449 | | { |
450 | | type Left = L; |
451 | | type Right = R; |
452 | | |
453 | 0 | fn consume<FL, FR>(&self, item: Either<L, R>, left: FL, right: FR) -> (FL, FR) |
454 | 0 | where |
455 | 0 | FL: Folder<L>, |
456 | 0 | FR: Folder<R>, |
457 | | { |
458 | 0 | match item { |
459 | 0 | Either::Left(item) => (left.consume(item), right), |
460 | 0 | Either::Right(item) => (left, right.consume(item)), |
461 | | } |
462 | 0 | } |
463 | | } |
464 | | |
465 | | impl<A, B, FromA, FromB> FromParallelIterator<(A, B)> for (FromA, FromB) |
466 | | where |
467 | | A: Send, |
468 | | B: Send, |
469 | | FromA: Send + FromParallelIterator<A>, |
470 | | FromB: Send + FromParallelIterator<B>, |
471 | | { |
472 | 0 | fn from_par_iter<I>(pi: I) -> Self |
473 | 0 | where |
474 | 0 | I: IntoParallelIterator<Item = (A, B)>, |
475 | | { |
476 | 0 | let (a, b): (Collector<FromA>, Collector<FromB>) = pi.into_par_iter().unzip(); |
477 | 0 | (a.result.unwrap(), b.result.unwrap()) |
478 | 0 | } |
479 | | } |
480 | | |
481 | | impl<L, R, A, B> FromParallelIterator<Either<L, R>> for (A, B) |
482 | | where |
483 | | L: Send, |
484 | | R: Send, |
485 | | A: Send + FromParallelIterator<L>, |
486 | | B: Send + FromParallelIterator<R>, |
487 | | { |
488 | 0 | fn from_par_iter<I>(pi: I) -> Self |
489 | 0 | where |
490 | 0 | I: IntoParallelIterator<Item = Either<L, R>>, |
491 | | { |
492 | 0 | fn identity<T>(x: T) -> T { |
493 | 0 | x |
494 | 0 | } |
495 | | |
496 | 0 | let (a, b): (Collector<A>, Collector<B>) = pi.into_par_iter().partition_map(identity); |
497 | 0 | (a.result.unwrap(), b.result.unwrap()) |
498 | 0 | } |
499 | | } |
500 | | |
501 | | /// Shim to implement a one-time `ParallelExtend` using `FromParallelIterator`. |
502 | | struct Collector<FromT> { |
503 | | result: Option<FromT>, |
504 | | } |
505 | | |
506 | | impl<FromT> Default for Collector<FromT> { |
507 | 0 | fn default() -> Self { |
508 | 0 | Collector { result: None } |
509 | 0 | } |
510 | | } |
511 | | |
512 | | impl<T, FromT> ParallelExtend<T> for Collector<FromT> |
513 | | where |
514 | | T: Send, |
515 | | FromT: Send + FromParallelIterator<T>, |
516 | | { |
517 | 0 | fn par_extend<I>(&mut self, pi: I) |
518 | 0 | where |
519 | 0 | I: IntoParallelIterator<Item = T>, |
520 | | { |
521 | 0 | debug_assert!(self.result.is_none()); |
522 | 0 | self.result = Some(pi.into_par_iter().collect()); |
523 | 0 | } |
524 | | } |