1use super::plumbing::*;
2use super::*;
3use std::iter::Fuse;
4
5#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
12#[derive(Debug, Clone)]
13pub struct Interleave<I, J>
14where
15 I: IndexedParallelIterator,
16 J: IndexedParallelIterator<Item = I::Item>,
17{
18 i: I,
19 j: J,
20}
21
22impl<I, J> Interleave<I, J>
23where
24 I: IndexedParallelIterator,
25 J: IndexedParallelIterator<Item = I::Item>,
26{
27 pub(super) fn new(i: I, j: J) -> Self {
29 Interleave { i, j }
30 }
31}
32
33impl<I, J> ParallelIterator for Interleave<I, J>
34where
35 I: IndexedParallelIterator,
36 J: IndexedParallelIterator<Item = I::Item>,
37{
38 type Item = I::Item;
39
40 fn drive_unindexed<C>(self, consumer: C) -> C::Result
41 where
42 C: Consumer<I::Item>,
43 {
44 bridge(self, consumer)
45 }
46
47 fn opt_len(&self) -> Option<usize> {
48 Some(self.len())
49 }
50}
51
52impl<I, J> IndexedParallelIterator for Interleave<I, J>
53where
54 I: IndexedParallelIterator,
55 J: IndexedParallelIterator<Item = I::Item>,
56{
57 fn drive<C>(self, consumer: C) -> C::Result
58 where
59 C: Consumer<Self::Item>,
60 {
61 bridge(self, consumer)
62 }
63
64 fn len(&self) -> usize {
65 self.i.len().checked_add(self.j.len()).expect("overflow")
66 }
67
68 fn with_producer<CB>(self, callback: CB) -> CB::Output
69 where
70 CB: ProducerCallback<Self::Item>,
71 {
72 let (i_len, j_len) = (self.i.len(), self.j.len());
73 return self.i.with_producer(CallbackI {
74 callback,
75 i_len,
76 j_len,
77 i_next: false,
78 j: self.j,
79 });
80
81 struct CallbackI<CB, J> {
82 callback: CB,
83 i_len: usize,
84 j_len: usize,
85 i_next: bool,
86 j: J,
87 }
88
89 impl<CB, J> ProducerCallback<J::Item> for CallbackI<CB, J>
90 where
91 J: IndexedParallelIterator,
92 CB: ProducerCallback<J::Item>,
93 {
94 type Output = CB::Output;
95
96 fn callback<I>(self, i_producer: I) -> Self::Output
97 where
98 I: Producer<Item = J::Item>,
99 {
100 self.j.with_producer(CallbackJ {
101 i_producer,
102 i_len: self.i_len,
103 j_len: self.j_len,
104 i_next: self.i_next,
105 callback: self.callback,
106 })
107 }
108 }
109
110 struct CallbackJ<CB, I> {
111 callback: CB,
112 i_len: usize,
113 j_len: usize,
114 i_next: bool,
115 i_producer: I,
116 }
117
118 impl<CB, I> ProducerCallback<I::Item> for CallbackJ<CB, I>
119 where
120 I: Producer,
121 CB: ProducerCallback<I::Item>,
122 {
123 type Output = CB::Output;
124
125 fn callback<J>(self, j_producer: J) -> Self::Output
126 where
127 J: Producer<Item = I::Item>,
128 {
129 let producer = InterleaveProducer::new(
130 self.i_producer,
131 j_producer,
132 self.i_len,
133 self.j_len,
134 self.i_next,
135 );
136 self.callback.callback(producer)
137 }
138 }
139 }
140}
141
142struct InterleaveProducer<I, J>
143where
144 I: Producer,
145 J: Producer<Item = I::Item>,
146{
147 i: I,
148 j: J,
149 i_len: usize,
150 j_len: usize,
151 i_next: bool,
152}
153
154impl<I, J> InterleaveProducer<I, J>
155where
156 I: Producer,
157 J: Producer<Item = I::Item>,
158{
159 fn new(i: I, j: J, i_len: usize, j_len: usize, i_next: bool) -> InterleaveProducer<I, J> {
160 InterleaveProducer {
161 i,
162 j,
163 i_len,
164 j_len,
165 i_next,
166 }
167 }
168}
169
170impl<I, J> Producer for InterleaveProducer<I, J>
171where
172 I: Producer,
173 J: Producer<Item = I::Item>,
174{
175 type Item = I::Item;
176 type IntoIter = InterleaveSeq<I::IntoIter, J::IntoIter>;
177
178 fn into_iter(self) -> Self::IntoIter {
179 InterleaveSeq {
180 i: self.i.into_iter().fuse(),
181 j: self.j.into_iter().fuse(),
182 i_next: self.i_next,
183 }
184 }
185
186 fn min_len(&self) -> usize {
187 Ord::max(self.i.min_len(), self.j.min_len())
188 }
189
190 fn max_len(&self) -> usize {
191 Ord::min(self.i.max_len(), self.j.max_len())
192 }
193
194 fn split_at(self, index: usize) -> (Self, Self) {
207 #[inline]
208 fn odd_offset(flag: bool) -> usize {
209 (!flag) as usize
210 }
211
212 let even = index % 2 == 0;
213 let idx = index >> 1;
214
215 let (i_idx, j_idx) = (
217 idx + odd_offset(even || self.i_next),
218 idx + odd_offset(even || !self.i_next),
219 );
220
221 let (i_split, j_split) = if self.i_len >= i_idx && self.j_len >= j_idx {
222 (i_idx, j_idx)
223 } else if self.i_len >= i_idx {
224 (index - self.j_len, self.j_len)
226 } else {
227 (self.i_len, index - self.i_len)
229 };
230
231 let trailing_i_next = even == self.i_next;
232 let (i_left, i_right) = self.i.split_at(i_split);
233 let (j_left, j_right) = self.j.split_at(j_split);
234
235 (
236 InterleaveProducer::new(i_left, j_left, i_split, j_split, self.i_next),
237 InterleaveProducer::new(
238 i_right,
239 j_right,
240 self.i_len - i_split,
241 self.j_len - j_split,
242 trailing_i_next,
243 ),
244 )
245 }
246}
247
248struct InterleaveSeq<I, J> {
253 i: Fuse<I>,
254 j: Fuse<J>,
255
256 i_next: bool,
260}
261
262impl<I, J> Iterator for InterleaveSeq<I, J>
267where
268 I: Iterator,
269 J: Iterator<Item = I::Item>,
270{
271 type Item = I::Item;
272
273 #[inline]
274 fn next(&mut self) -> Option<Self::Item> {
275 self.i_next = !self.i_next;
276 if self.i_next {
277 match self.i.next() {
278 None => self.j.next(),
279 r => r,
280 }
281 } else {
282 match self.j.next() {
283 None => self.i.next(),
284 r => r,
285 }
286 }
287 }
288
289 fn size_hint(&self) -> (usize, Option<usize>) {
290 let (ih, jh) = (self.i.size_hint(), self.j.size_hint());
291 let min = ih.0.saturating_add(jh.0);
292 let max = match (ih.1, jh.1) {
293 (Some(x), Some(y)) => x.checked_add(y),
294 _ => None,
295 };
296 (min, max)
297 }
298}
299
300impl<I, J> DoubleEndedIterator for InterleaveSeq<I, J>
306where
307 I: DoubleEndedIterator + ExactSizeIterator,
308 J: DoubleEndedIterator<Item = I::Item> + ExactSizeIterator<Item = I::Item>,
309{
310 #[inline]
311 fn next_back(&mut self) -> Option<I::Item> {
312 match self.i.len().cmp(&self.j.len()) {
313 Ordering::Less => self.j.next_back(),
314 Ordering::Equal => {
315 if self.i_next {
316 self.i.next_back()
317 } else {
318 self.j.next_back()
319 }
320 }
321 Ordering::Greater => self.i.next_back(),
322 }
323 }
324}
325
326impl<I, J> ExactSizeIterator for InterleaveSeq<I, J>
327where
328 I: ExactSizeIterator,
329 J: ExactSizeIterator<Item = I::Item>,
330{
331 #[inline]
332 fn len(&self) -> usize {
333 self.i.len() + self.j.len()
334 }
335}