Coverage Report

Created: 2026-01-22 07:28

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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_len
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>::opt_len
Unexecuted 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_len
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>::opt_len
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>::opt_len
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>::opt_len
Unexecuted 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
}