re_query/range_zip/
generated.rs

1// This file was generated using `cargo r -p re_query --all-features --bin range_zip`.
2// DO NOT EDIT.
3
4// ---
5
6#![expect(clippy::iter_on_single_items)]
7#![expect(clippy::too_many_arguments)]
8#![expect(clippy::type_complexity)]
9
10use std::iter::Peekable;
11
12/// Returns a new [`RangeZip1x1`] iterator.
13///
14/// The number of elements in a range zip iterator corresponds to the number of elements in the
15/// shortest of its required iterators (`r0`).
16///
17/// Each call to `next` is guaranteed to yield the next value for each required iterator,
18/// as well as the most recent index amongst all of them.
19///
20/// Optional iterators accumulate their state and yield their most recent value (if any),
21/// each time the required iterators fire.
22pub fn range_zip_1x1<Idx, IR0, R0, IO0, O0>(
23    r0: IR0,
24    o0: IO0,
25) -> RangeZip1x1<Idx, IR0::IntoIter, R0, IO0::IntoIter, O0>
26where
27    Idx: std::cmp::Ord,
28    IR0: IntoIterator<Item = (Idx, R0)>,
29    IO0: IntoIterator<Item = (Idx, O0)>,
30{
31    RangeZip1x1 {
32        r0: r0.into_iter(),
33        o0: o0.into_iter().peekable(),
34
35        o0_data_latest: None,
36    }
37}
38
39/// Implements a range zip iterator combinator with 2 required iterators and 2 optional
40/// iterators.
41///
42/// See [`range_zip_1x1`] for more information.
43pub struct RangeZip1x1<Idx, IR0, R0, IO0, O0>
44where
45    Idx: std::cmp::Ord,
46    IR0: Iterator<Item = (Idx, R0)>,
47    IO0: Iterator<Item = (Idx, O0)>,
48{
49    r0: IR0,
50    o0: Peekable<IO0>,
51
52    o0_data_latest: Option<O0>,
53}
54
55impl<Idx, IR0, R0, IO0, O0> Iterator for RangeZip1x1<Idx, IR0, R0, IO0, O0>
56where
57    Idx: std::cmp::Ord,
58    IR0: Iterator<Item = (Idx, R0)>,
59    IO0: Iterator<Item = (Idx, O0)>,
60    O0: Clone,
61{
62    type Item = (Idx, R0, Option<O0>);
63
64    #[inline]
65    fn next(&mut self) -> Option<Self::Item> {
66        let Self {
67            r0,
68            o0,
69            o0_data_latest,
70        } = self;
71
72        let (r0_index, r0_data) = r0.next()?;
73
74        let max_index = [r0_index].into_iter().max()?;
75
76        let mut o0_data = None;
77        while let Some((_, data)) = o0.next_if(|(index, _)| index <= &max_index) {
78            o0_data = Some(data);
79        }
80        let o0_data = o0_data.or(o0_data_latest.take());
81        o0_data_latest.clone_from(&o0_data);
82
83        Some((max_index, r0_data, o0_data))
84    }
85}
86
87/// Returns a new [`RangeZip1x2`] iterator.
88///
89/// The number of elements in a range zip iterator corresponds to the number of elements in the
90/// shortest of its required iterators (`r0`).
91///
92/// Each call to `next` is guaranteed to yield the next value for each required iterator,
93/// as well as the most recent index amongst all of them.
94///
95/// Optional iterators accumulate their state and yield their most recent value (if any),
96/// each time the required iterators fire.
97pub fn range_zip_1x2<Idx, IR0, R0, IO0, O0, IO1, O1>(
98    r0: IR0,
99    o0: IO0,
100    o1: IO1,
101) -> RangeZip1x2<Idx, IR0::IntoIter, R0, IO0::IntoIter, O0, IO1::IntoIter, O1>
102where
103    Idx: std::cmp::Ord,
104    IR0: IntoIterator<Item = (Idx, R0)>,
105    IO0: IntoIterator<Item = (Idx, O0)>,
106    IO1: IntoIterator<Item = (Idx, O1)>,
107{
108    RangeZip1x2 {
109        r0: r0.into_iter(),
110        o0: o0.into_iter().peekable(),
111        o1: o1.into_iter().peekable(),
112
113        o0_data_latest: None,
114        o1_data_latest: None,
115    }
116}
117
118/// Implements a range zip iterator combinator with 2 required iterators and 2 optional
119/// iterators.
120///
121/// See [`range_zip_1x2`] for more information.
122pub struct RangeZip1x2<Idx, IR0, R0, IO0, O0, IO1, O1>
123where
124    Idx: std::cmp::Ord,
125    IR0: Iterator<Item = (Idx, R0)>,
126    IO0: Iterator<Item = (Idx, O0)>,
127    IO1: Iterator<Item = (Idx, O1)>,
128{
129    r0: IR0,
130    o0: Peekable<IO0>,
131    o1: Peekable<IO1>,
132
133    o0_data_latest: Option<O0>,
134    o1_data_latest: Option<O1>,
135}
136
137impl<Idx, IR0, R0, IO0, O0, IO1, O1> Iterator for RangeZip1x2<Idx, IR0, R0, IO0, O0, IO1, O1>
138where
139    Idx: std::cmp::Ord,
140    IR0: Iterator<Item = (Idx, R0)>,
141    IO0: Iterator<Item = (Idx, O0)>,
142    IO1: Iterator<Item = (Idx, O1)>,
143    O0: Clone,
144    O1: Clone,
145{
146    type Item = (Idx, R0, Option<O0>, Option<O1>);
147
148    #[inline]
149    fn next(&mut self) -> Option<Self::Item> {
150        let Self {
151            r0,
152            o0,
153            o1,
154            o0_data_latest,
155            o1_data_latest,
156        } = self;
157
158        let (r0_index, r0_data) = r0.next()?;
159
160        let max_index = [r0_index].into_iter().max()?;
161
162        let mut o0_data = None;
163        while let Some((_, data)) = o0.next_if(|(index, _)| index <= &max_index) {
164            o0_data = Some(data);
165        }
166        let o0_data = o0_data.or(o0_data_latest.take());
167        o0_data_latest.clone_from(&o0_data);
168
169        let mut o1_data = None;
170        while let Some((_, data)) = o1.next_if(|(index, _)| index <= &max_index) {
171            o1_data = Some(data);
172        }
173        let o1_data = o1_data.or(o1_data_latest.take());
174        o1_data_latest.clone_from(&o1_data);
175
176        Some((max_index, r0_data, o0_data, o1_data))
177    }
178}
179
180/// Returns a new [`RangeZip1x3`] iterator.
181///
182/// The number of elements in a range zip iterator corresponds to the number of elements in the
183/// shortest of its required iterators (`r0`).
184///
185/// Each call to `next` is guaranteed to yield the next value for each required iterator,
186/// as well as the most recent index amongst all of them.
187///
188/// Optional iterators accumulate their state and yield their most recent value (if any),
189/// each time the required iterators fire.
190pub fn range_zip_1x3<Idx, IR0, R0, IO0, O0, IO1, O1, IO2, O2>(
191    r0: IR0,
192    o0: IO0,
193    o1: IO1,
194    o2: IO2,
195) -> RangeZip1x3<Idx, IR0::IntoIter, R0, IO0::IntoIter, O0, IO1::IntoIter, O1, IO2::IntoIter, O2>
196where
197    Idx: std::cmp::Ord,
198    IR0: IntoIterator<Item = (Idx, R0)>,
199    IO0: IntoIterator<Item = (Idx, O0)>,
200    IO1: IntoIterator<Item = (Idx, O1)>,
201    IO2: IntoIterator<Item = (Idx, O2)>,
202{
203    RangeZip1x3 {
204        r0: r0.into_iter(),
205        o0: o0.into_iter().peekable(),
206        o1: o1.into_iter().peekable(),
207        o2: o2.into_iter().peekable(),
208
209        o0_data_latest: None,
210        o1_data_latest: None,
211        o2_data_latest: None,
212    }
213}
214
215/// Implements a range zip iterator combinator with 2 required iterators and 2 optional
216/// iterators.
217///
218/// See [`range_zip_1x3`] for more information.
219pub struct RangeZip1x3<Idx, IR0, R0, IO0, O0, IO1, O1, IO2, O2>
220where
221    Idx: std::cmp::Ord,
222    IR0: Iterator<Item = (Idx, R0)>,
223    IO0: Iterator<Item = (Idx, O0)>,
224    IO1: Iterator<Item = (Idx, O1)>,
225    IO2: Iterator<Item = (Idx, O2)>,
226{
227    r0: IR0,
228    o0: Peekable<IO0>,
229    o1: Peekable<IO1>,
230    o2: Peekable<IO2>,
231
232    o0_data_latest: Option<O0>,
233    o1_data_latest: Option<O1>,
234    o2_data_latest: Option<O2>,
235}
236
237impl<Idx, IR0, R0, IO0, O0, IO1, O1, IO2, O2> Iterator
238    for RangeZip1x3<Idx, IR0, R0, IO0, O0, IO1, O1, IO2, O2>
239where
240    Idx: std::cmp::Ord,
241    IR0: Iterator<Item = (Idx, R0)>,
242    IO0: Iterator<Item = (Idx, O0)>,
243    IO1: Iterator<Item = (Idx, O1)>,
244    IO2: Iterator<Item = (Idx, O2)>,
245    O0: Clone,
246    O1: Clone,
247    O2: Clone,
248{
249    type Item = (Idx, R0, Option<O0>, Option<O1>, Option<O2>);
250
251    #[inline]
252    fn next(&mut self) -> Option<Self::Item> {
253        let Self {
254            r0,
255            o0,
256            o1,
257            o2,
258            o0_data_latest,
259            o1_data_latest,
260            o2_data_latest,
261        } = self;
262
263        let (r0_index, r0_data) = r0.next()?;
264
265        let max_index = [r0_index].into_iter().max()?;
266
267        let mut o0_data = None;
268        while let Some((_, data)) = o0.next_if(|(index, _)| index <= &max_index) {
269            o0_data = Some(data);
270        }
271        let o0_data = o0_data.or(o0_data_latest.take());
272        o0_data_latest.clone_from(&o0_data);
273
274        let mut o1_data = None;
275        while let Some((_, data)) = o1.next_if(|(index, _)| index <= &max_index) {
276            o1_data = Some(data);
277        }
278        let o1_data = o1_data.or(o1_data_latest.take());
279        o1_data_latest.clone_from(&o1_data);
280
281        let mut o2_data = None;
282        while let Some((_, data)) = o2.next_if(|(index, _)| index <= &max_index) {
283            o2_data = Some(data);
284        }
285        let o2_data = o2_data.or(o2_data_latest.take());
286        o2_data_latest.clone_from(&o2_data);
287
288        Some((max_index, r0_data, o0_data, o1_data, o2_data))
289    }
290}
291
292/// Returns a new [`RangeZip1x4`] iterator.
293///
294/// The number of elements in a range zip iterator corresponds to the number of elements in the
295/// shortest of its required iterators (`r0`).
296///
297/// Each call to `next` is guaranteed to yield the next value for each required iterator,
298/// as well as the most recent index amongst all of them.
299///
300/// Optional iterators accumulate their state and yield their most recent value (if any),
301/// each time the required iterators fire.
302pub fn range_zip_1x4<Idx, IR0, R0, IO0, O0, IO1, O1, IO2, O2, IO3, O3>(
303    r0: IR0,
304    o0: IO0,
305    o1: IO1,
306    o2: IO2,
307    o3: IO3,
308) -> RangeZip1x4<
309    Idx,
310    IR0::IntoIter,
311    R0,
312    IO0::IntoIter,
313    O0,
314    IO1::IntoIter,
315    O1,
316    IO2::IntoIter,
317    O2,
318    IO3::IntoIter,
319    O3,
320>
321where
322    Idx: std::cmp::Ord,
323    IR0: IntoIterator<Item = (Idx, R0)>,
324    IO0: IntoIterator<Item = (Idx, O0)>,
325    IO1: IntoIterator<Item = (Idx, O1)>,
326    IO2: IntoIterator<Item = (Idx, O2)>,
327    IO3: IntoIterator<Item = (Idx, O3)>,
328{
329    RangeZip1x4 {
330        r0: r0.into_iter(),
331        o0: o0.into_iter().peekable(),
332        o1: o1.into_iter().peekable(),
333        o2: o2.into_iter().peekable(),
334        o3: o3.into_iter().peekable(),
335
336        o0_data_latest: None,
337        o1_data_latest: None,
338        o2_data_latest: None,
339        o3_data_latest: None,
340    }
341}
342
343/// Implements a range zip iterator combinator with 2 required iterators and 2 optional
344/// iterators.
345///
346/// See [`range_zip_1x4`] for more information.
347pub struct RangeZip1x4<Idx, IR0, R0, IO0, O0, IO1, O1, IO2, O2, IO3, O3>
348where
349    Idx: std::cmp::Ord,
350    IR0: Iterator<Item = (Idx, R0)>,
351    IO0: Iterator<Item = (Idx, O0)>,
352    IO1: Iterator<Item = (Idx, O1)>,
353    IO2: Iterator<Item = (Idx, O2)>,
354    IO3: Iterator<Item = (Idx, O3)>,
355{
356    r0: IR0,
357    o0: Peekable<IO0>,
358    o1: Peekable<IO1>,
359    o2: Peekable<IO2>,
360    o3: Peekable<IO3>,
361
362    o0_data_latest: Option<O0>,
363    o1_data_latest: Option<O1>,
364    o2_data_latest: Option<O2>,
365    o3_data_latest: Option<O3>,
366}
367
368impl<Idx, IR0, R0, IO0, O0, IO1, O1, IO2, O2, IO3, O3> Iterator
369    for RangeZip1x4<Idx, IR0, R0, IO0, O0, IO1, O1, IO2, O2, IO3, O3>
370where
371    Idx: std::cmp::Ord,
372    IR0: Iterator<Item = (Idx, R0)>,
373    IO0: Iterator<Item = (Idx, O0)>,
374    IO1: Iterator<Item = (Idx, O1)>,
375    IO2: Iterator<Item = (Idx, O2)>,
376    IO3: Iterator<Item = (Idx, O3)>,
377    O0: Clone,
378    O1: Clone,
379    O2: Clone,
380    O3: Clone,
381{
382    type Item = (Idx, R0, Option<O0>, Option<O1>, Option<O2>, Option<O3>);
383
384    #[inline]
385    fn next(&mut self) -> Option<Self::Item> {
386        let Self {
387            r0,
388            o0,
389            o1,
390            o2,
391            o3,
392            o0_data_latest,
393            o1_data_latest,
394            o2_data_latest,
395            o3_data_latest,
396        } = self;
397
398        let (r0_index, r0_data) = r0.next()?;
399
400        let max_index = [r0_index].into_iter().max()?;
401
402        let mut o0_data = None;
403        while let Some((_, data)) = o0.next_if(|(index, _)| index <= &max_index) {
404            o0_data = Some(data);
405        }
406        let o0_data = o0_data.or(o0_data_latest.take());
407        o0_data_latest.clone_from(&o0_data);
408
409        let mut o1_data = None;
410        while let Some((_, data)) = o1.next_if(|(index, _)| index <= &max_index) {
411            o1_data = Some(data);
412        }
413        let o1_data = o1_data.or(o1_data_latest.take());
414        o1_data_latest.clone_from(&o1_data);
415
416        let mut o2_data = None;
417        while let Some((_, data)) = o2.next_if(|(index, _)| index <= &max_index) {
418            o2_data = Some(data);
419        }
420        let o2_data = o2_data.or(o2_data_latest.take());
421        o2_data_latest.clone_from(&o2_data);
422
423        let mut o3_data = None;
424        while let Some((_, data)) = o3.next_if(|(index, _)| index <= &max_index) {
425            o3_data = Some(data);
426        }
427        let o3_data = o3_data.or(o3_data_latest.take());
428        o3_data_latest.clone_from(&o3_data);
429
430        Some((max_index, r0_data, o0_data, o1_data, o2_data, o3_data))
431    }
432}
433
434/// Returns a new [`RangeZip1x5`] iterator.
435///
436/// The number of elements in a range zip iterator corresponds to the number of elements in the
437/// shortest of its required iterators (`r0`).
438///
439/// Each call to `next` is guaranteed to yield the next value for each required iterator,
440/// as well as the most recent index amongst all of them.
441///
442/// Optional iterators accumulate their state and yield their most recent value (if any),
443/// each time the required iterators fire.
444pub fn range_zip_1x5<Idx, IR0, R0, IO0, O0, IO1, O1, IO2, O2, IO3, O3, IO4, O4>(
445    r0: IR0,
446    o0: IO0,
447    o1: IO1,
448    o2: IO2,
449    o3: IO3,
450    o4: IO4,
451) -> RangeZip1x5<
452    Idx,
453    IR0::IntoIter,
454    R0,
455    IO0::IntoIter,
456    O0,
457    IO1::IntoIter,
458    O1,
459    IO2::IntoIter,
460    O2,
461    IO3::IntoIter,
462    O3,
463    IO4::IntoIter,
464    O4,
465>
466where
467    Idx: std::cmp::Ord,
468    IR0: IntoIterator<Item = (Idx, R0)>,
469    IO0: IntoIterator<Item = (Idx, O0)>,
470    IO1: IntoIterator<Item = (Idx, O1)>,
471    IO2: IntoIterator<Item = (Idx, O2)>,
472    IO3: IntoIterator<Item = (Idx, O3)>,
473    IO4: IntoIterator<Item = (Idx, O4)>,
474{
475    RangeZip1x5 {
476        r0: r0.into_iter(),
477        o0: o0.into_iter().peekable(),
478        o1: o1.into_iter().peekable(),
479        o2: o2.into_iter().peekable(),
480        o3: o3.into_iter().peekable(),
481        o4: o4.into_iter().peekable(),
482
483        o0_data_latest: None,
484        o1_data_latest: None,
485        o2_data_latest: None,
486        o3_data_latest: None,
487        o4_data_latest: None,
488    }
489}
490
491/// Implements a range zip iterator combinator with 2 required iterators and 2 optional
492/// iterators.
493///
494/// See [`range_zip_1x5`] for more information.
495pub struct RangeZip1x5<Idx, IR0, R0, IO0, O0, IO1, O1, IO2, O2, IO3, O3, IO4, O4>
496where
497    Idx: std::cmp::Ord,
498    IR0: Iterator<Item = (Idx, R0)>,
499    IO0: Iterator<Item = (Idx, O0)>,
500    IO1: Iterator<Item = (Idx, O1)>,
501    IO2: Iterator<Item = (Idx, O2)>,
502    IO3: Iterator<Item = (Idx, O3)>,
503    IO4: Iterator<Item = (Idx, O4)>,
504{
505    r0: IR0,
506    o0: Peekable<IO0>,
507    o1: Peekable<IO1>,
508    o2: Peekable<IO2>,
509    o3: Peekable<IO3>,
510    o4: Peekable<IO4>,
511
512    o0_data_latest: Option<O0>,
513    o1_data_latest: Option<O1>,
514    o2_data_latest: Option<O2>,
515    o3_data_latest: Option<O3>,
516    o4_data_latest: Option<O4>,
517}
518
519impl<Idx, IR0, R0, IO0, O0, IO1, O1, IO2, O2, IO3, O3, IO4, O4> Iterator
520    for RangeZip1x5<Idx, IR0, R0, IO0, O0, IO1, O1, IO2, O2, IO3, O3, IO4, O4>
521where
522    Idx: std::cmp::Ord,
523    IR0: Iterator<Item = (Idx, R0)>,
524    IO0: Iterator<Item = (Idx, O0)>,
525    IO1: Iterator<Item = (Idx, O1)>,
526    IO2: Iterator<Item = (Idx, O2)>,
527    IO3: Iterator<Item = (Idx, O3)>,
528    IO4: Iterator<Item = (Idx, O4)>,
529    O0: Clone,
530    O1: Clone,
531    O2: Clone,
532    O3: Clone,
533    O4: Clone,
534{
535    type Item = (
536        Idx,
537        R0,
538        Option<O0>,
539        Option<O1>,
540        Option<O2>,
541        Option<O3>,
542        Option<O4>,
543    );
544
545    #[inline]
546    fn next(&mut self) -> Option<Self::Item> {
547        let Self {
548            r0,
549            o0,
550            o1,
551            o2,
552            o3,
553            o4,
554            o0_data_latest,
555            o1_data_latest,
556            o2_data_latest,
557            o3_data_latest,
558            o4_data_latest,
559        } = self;
560
561        let (r0_index, r0_data) = r0.next()?;
562
563        let max_index = [r0_index].into_iter().max()?;
564
565        let mut o0_data = None;
566        while let Some((_, data)) = o0.next_if(|(index, _)| index <= &max_index) {
567            o0_data = Some(data);
568        }
569        let o0_data = o0_data.or(o0_data_latest.take());
570        o0_data_latest.clone_from(&o0_data);
571
572        let mut o1_data = None;
573        while let Some((_, data)) = o1.next_if(|(index, _)| index <= &max_index) {
574            o1_data = Some(data);
575        }
576        let o1_data = o1_data.or(o1_data_latest.take());
577        o1_data_latest.clone_from(&o1_data);
578
579        let mut o2_data = None;
580        while let Some((_, data)) = o2.next_if(|(index, _)| index <= &max_index) {
581            o2_data = Some(data);
582        }
583        let o2_data = o2_data.or(o2_data_latest.take());
584        o2_data_latest.clone_from(&o2_data);
585
586        let mut o3_data = None;
587        while let Some((_, data)) = o3.next_if(|(index, _)| index <= &max_index) {
588            o3_data = Some(data);
589        }
590        let o3_data = o3_data.or(o3_data_latest.take());
591        o3_data_latest.clone_from(&o3_data);
592
593        let mut o4_data = None;
594        while let Some((_, data)) = o4.next_if(|(index, _)| index <= &max_index) {
595            o4_data = Some(data);
596        }
597        let o4_data = o4_data.or(o4_data_latest.take());
598        o4_data_latest.clone_from(&o4_data);
599
600        Some((
601            max_index, r0_data, o0_data, o1_data, o2_data, o3_data, o4_data,
602        ))
603    }
604}
605
606/// Returns a new [`RangeZip1x6`] iterator.
607///
608/// The number of elements in a range zip iterator corresponds to the number of elements in the
609/// shortest of its required iterators (`r0`).
610///
611/// Each call to `next` is guaranteed to yield the next value for each required iterator,
612/// as well as the most recent index amongst all of them.
613///
614/// Optional iterators accumulate their state and yield their most recent value (if any),
615/// each time the required iterators fire.
616pub fn range_zip_1x6<Idx, IR0, R0, IO0, O0, IO1, O1, IO2, O2, IO3, O3, IO4, O4, IO5, O5>(
617    r0: IR0,
618    o0: IO0,
619    o1: IO1,
620    o2: IO2,
621    o3: IO3,
622    o4: IO4,
623    o5: IO5,
624) -> RangeZip1x6<
625    Idx,
626    IR0::IntoIter,
627    R0,
628    IO0::IntoIter,
629    O0,
630    IO1::IntoIter,
631    O1,
632    IO2::IntoIter,
633    O2,
634    IO3::IntoIter,
635    O3,
636    IO4::IntoIter,
637    O4,
638    IO5::IntoIter,
639    O5,
640>
641where
642    Idx: std::cmp::Ord,
643    IR0: IntoIterator<Item = (Idx, R0)>,
644    IO0: IntoIterator<Item = (Idx, O0)>,
645    IO1: IntoIterator<Item = (Idx, O1)>,
646    IO2: IntoIterator<Item = (Idx, O2)>,
647    IO3: IntoIterator<Item = (Idx, O3)>,
648    IO4: IntoIterator<Item = (Idx, O4)>,
649    IO5: IntoIterator<Item = (Idx, O5)>,
650{
651    RangeZip1x6 {
652        r0: r0.into_iter(),
653        o0: o0.into_iter().peekable(),
654        o1: o1.into_iter().peekable(),
655        o2: o2.into_iter().peekable(),
656        o3: o3.into_iter().peekable(),
657        o4: o4.into_iter().peekable(),
658        o5: o5.into_iter().peekable(),
659
660        o0_data_latest: None,
661        o1_data_latest: None,
662        o2_data_latest: None,
663        o3_data_latest: None,
664        o4_data_latest: None,
665        o5_data_latest: None,
666    }
667}
668
669/// Implements a range zip iterator combinator with 2 required iterators and 2 optional
670/// iterators.
671///
672/// See [`range_zip_1x6`] for more information.
673pub struct RangeZip1x6<Idx, IR0, R0, IO0, O0, IO1, O1, IO2, O2, IO3, O3, IO4, O4, IO5, O5>
674where
675    Idx: std::cmp::Ord,
676    IR0: Iterator<Item = (Idx, R0)>,
677    IO0: Iterator<Item = (Idx, O0)>,
678    IO1: Iterator<Item = (Idx, O1)>,
679    IO2: Iterator<Item = (Idx, O2)>,
680    IO3: Iterator<Item = (Idx, O3)>,
681    IO4: Iterator<Item = (Idx, O4)>,
682    IO5: Iterator<Item = (Idx, O5)>,
683{
684    r0: IR0,
685    o0: Peekable<IO0>,
686    o1: Peekable<IO1>,
687    o2: Peekable<IO2>,
688    o3: Peekable<IO3>,
689    o4: Peekable<IO4>,
690    o5: Peekable<IO5>,
691
692    o0_data_latest: Option<O0>,
693    o1_data_latest: Option<O1>,
694    o2_data_latest: Option<O2>,
695    o3_data_latest: Option<O3>,
696    o4_data_latest: Option<O4>,
697    o5_data_latest: Option<O5>,
698}
699
700impl<Idx, IR0, R0, IO0, O0, IO1, O1, IO2, O2, IO3, O3, IO4, O4, IO5, O5> Iterator
701    for RangeZip1x6<Idx, IR0, R0, IO0, O0, IO1, O1, IO2, O2, IO3, O3, IO4, O4, IO5, O5>
702where
703    Idx: std::cmp::Ord,
704    IR0: Iterator<Item = (Idx, R0)>,
705    IO0: Iterator<Item = (Idx, O0)>,
706    IO1: Iterator<Item = (Idx, O1)>,
707    IO2: Iterator<Item = (Idx, O2)>,
708    IO3: Iterator<Item = (Idx, O3)>,
709    IO4: Iterator<Item = (Idx, O4)>,
710    IO5: Iterator<Item = (Idx, O5)>,
711    O0: Clone,
712    O1: Clone,
713    O2: Clone,
714    O3: Clone,
715    O4: Clone,
716    O5: Clone,
717{
718    type Item = (
719        Idx,
720        R0,
721        Option<O0>,
722        Option<O1>,
723        Option<O2>,
724        Option<O3>,
725        Option<O4>,
726        Option<O5>,
727    );
728
729    #[inline]
730    fn next(&mut self) -> Option<Self::Item> {
731        let Self {
732            r0,
733            o0,
734            o1,
735            o2,
736            o3,
737            o4,
738            o5,
739            o0_data_latest,
740            o1_data_latest,
741            o2_data_latest,
742            o3_data_latest,
743            o4_data_latest,
744            o5_data_latest,
745        } = self;
746
747        let (r0_index, r0_data) = r0.next()?;
748
749        let max_index = [r0_index].into_iter().max()?;
750
751        let mut o0_data = None;
752        while let Some((_, data)) = o0.next_if(|(index, _)| index <= &max_index) {
753            o0_data = Some(data);
754        }
755        let o0_data = o0_data.or(o0_data_latest.take());
756        o0_data_latest.clone_from(&o0_data);
757
758        let mut o1_data = None;
759        while let Some((_, data)) = o1.next_if(|(index, _)| index <= &max_index) {
760            o1_data = Some(data);
761        }
762        let o1_data = o1_data.or(o1_data_latest.take());
763        o1_data_latest.clone_from(&o1_data);
764
765        let mut o2_data = None;
766        while let Some((_, data)) = o2.next_if(|(index, _)| index <= &max_index) {
767            o2_data = Some(data);
768        }
769        let o2_data = o2_data.or(o2_data_latest.take());
770        o2_data_latest.clone_from(&o2_data);
771
772        let mut o3_data = None;
773        while let Some((_, data)) = o3.next_if(|(index, _)| index <= &max_index) {
774            o3_data = Some(data);
775        }
776        let o3_data = o3_data.or(o3_data_latest.take());
777        o3_data_latest.clone_from(&o3_data);
778
779        let mut o4_data = None;
780        while let Some((_, data)) = o4.next_if(|(index, _)| index <= &max_index) {
781            o4_data = Some(data);
782        }
783        let o4_data = o4_data.or(o4_data_latest.take());
784        o4_data_latest.clone_from(&o4_data);
785
786        let mut o5_data = None;
787        while let Some((_, data)) = o5.next_if(|(index, _)| index <= &max_index) {
788            o5_data = Some(data);
789        }
790        let o5_data = o5_data.or(o5_data_latest.take());
791        o5_data_latest.clone_from(&o5_data);
792
793        Some((
794            max_index, r0_data, o0_data, o1_data, o2_data, o3_data, o4_data, o5_data,
795        ))
796    }
797}
798
799/// Returns a new [`RangeZip1x7`] iterator.
800///
801/// The number of elements in a range zip iterator corresponds to the number of elements in the
802/// shortest of its required iterators (`r0`).
803///
804/// Each call to `next` is guaranteed to yield the next value for each required iterator,
805/// as well as the most recent index amongst all of them.
806///
807/// Optional iterators accumulate their state and yield their most recent value (if any),
808/// each time the required iterators fire.
809pub fn range_zip_1x7<Idx, IR0, R0, IO0, O0, IO1, O1, IO2, O2, IO3, O3, IO4, O4, IO5, O5, IO6, O6>(
810    r0: IR0,
811    o0: IO0,
812    o1: IO1,
813    o2: IO2,
814    o3: IO3,
815    o4: IO4,
816    o5: IO5,
817    o6: IO6,
818) -> RangeZip1x7<
819    Idx,
820    IR0::IntoIter,
821    R0,
822    IO0::IntoIter,
823    O0,
824    IO1::IntoIter,
825    O1,
826    IO2::IntoIter,
827    O2,
828    IO3::IntoIter,
829    O3,
830    IO4::IntoIter,
831    O4,
832    IO5::IntoIter,
833    O5,
834    IO6::IntoIter,
835    O6,
836>
837where
838    Idx: std::cmp::Ord,
839    IR0: IntoIterator<Item = (Idx, R0)>,
840    IO0: IntoIterator<Item = (Idx, O0)>,
841    IO1: IntoIterator<Item = (Idx, O1)>,
842    IO2: IntoIterator<Item = (Idx, O2)>,
843    IO3: IntoIterator<Item = (Idx, O3)>,
844    IO4: IntoIterator<Item = (Idx, O4)>,
845    IO5: IntoIterator<Item = (Idx, O5)>,
846    IO6: IntoIterator<Item = (Idx, O6)>,
847{
848    RangeZip1x7 {
849        r0: r0.into_iter(),
850        o0: o0.into_iter().peekable(),
851        o1: o1.into_iter().peekable(),
852        o2: o2.into_iter().peekable(),
853        o3: o3.into_iter().peekable(),
854        o4: o4.into_iter().peekable(),
855        o5: o5.into_iter().peekable(),
856        o6: o6.into_iter().peekable(),
857
858        o0_data_latest: None,
859        o1_data_latest: None,
860        o2_data_latest: None,
861        o3_data_latest: None,
862        o4_data_latest: None,
863        o5_data_latest: None,
864        o6_data_latest: None,
865    }
866}
867
868/// Implements a range zip iterator combinator with 2 required iterators and 2 optional
869/// iterators.
870///
871/// See [`range_zip_1x7`] for more information.
872pub struct RangeZip1x7<Idx, IR0, R0, IO0, O0, IO1, O1, IO2, O2, IO3, O3, IO4, O4, IO5, O5, IO6, O6>
873where
874    Idx: std::cmp::Ord,
875    IR0: Iterator<Item = (Idx, R0)>,
876    IO0: Iterator<Item = (Idx, O0)>,
877    IO1: Iterator<Item = (Idx, O1)>,
878    IO2: Iterator<Item = (Idx, O2)>,
879    IO3: Iterator<Item = (Idx, O3)>,
880    IO4: Iterator<Item = (Idx, O4)>,
881    IO5: Iterator<Item = (Idx, O5)>,
882    IO6: Iterator<Item = (Idx, O6)>,
883{
884    r0: IR0,
885    o0: Peekable<IO0>,
886    o1: Peekable<IO1>,
887    o2: Peekable<IO2>,
888    o3: Peekable<IO3>,
889    o4: Peekable<IO4>,
890    o5: Peekable<IO5>,
891    o6: Peekable<IO6>,
892
893    o0_data_latest: Option<O0>,
894    o1_data_latest: Option<O1>,
895    o2_data_latest: Option<O2>,
896    o3_data_latest: Option<O3>,
897    o4_data_latest: Option<O4>,
898    o5_data_latest: Option<O5>,
899    o6_data_latest: Option<O6>,
900}
901
902impl<Idx, IR0, R0, IO0, O0, IO1, O1, IO2, O2, IO3, O3, IO4, O4, IO5, O5, IO6, O6> Iterator
903    for RangeZip1x7<Idx, IR0, R0, IO0, O0, IO1, O1, IO2, O2, IO3, O3, IO4, O4, IO5, O5, IO6, O6>
904where
905    Idx: std::cmp::Ord,
906    IR0: Iterator<Item = (Idx, R0)>,
907    IO0: Iterator<Item = (Idx, O0)>,
908    IO1: Iterator<Item = (Idx, O1)>,
909    IO2: Iterator<Item = (Idx, O2)>,
910    IO3: Iterator<Item = (Idx, O3)>,
911    IO4: Iterator<Item = (Idx, O4)>,
912    IO5: Iterator<Item = (Idx, O5)>,
913    IO6: Iterator<Item = (Idx, O6)>,
914    O0: Clone,
915    O1: Clone,
916    O2: Clone,
917    O3: Clone,
918    O4: Clone,
919    O5: Clone,
920    O6: Clone,
921{
922    type Item = (
923        Idx,
924        R0,
925        Option<O0>,
926        Option<O1>,
927        Option<O2>,
928        Option<O3>,
929        Option<O4>,
930        Option<O5>,
931        Option<O6>,
932    );
933
934    #[inline]
935    fn next(&mut self) -> Option<Self::Item> {
936        let Self {
937            r0,
938            o0,
939            o1,
940            o2,
941            o3,
942            o4,
943            o5,
944            o6,
945            o0_data_latest,
946            o1_data_latest,
947            o2_data_latest,
948            o3_data_latest,
949            o4_data_latest,
950            o5_data_latest,
951            o6_data_latest,
952        } = self;
953
954        let (r0_index, r0_data) = r0.next()?;
955
956        let max_index = [r0_index].into_iter().max()?;
957
958        let mut o0_data = None;
959        while let Some((_, data)) = o0.next_if(|(index, _)| index <= &max_index) {
960            o0_data = Some(data);
961        }
962        let o0_data = o0_data.or(o0_data_latest.take());
963        o0_data_latest.clone_from(&o0_data);
964
965        let mut o1_data = None;
966        while let Some((_, data)) = o1.next_if(|(index, _)| index <= &max_index) {
967            o1_data = Some(data);
968        }
969        let o1_data = o1_data.or(o1_data_latest.take());
970        o1_data_latest.clone_from(&o1_data);
971
972        let mut o2_data = None;
973        while let Some((_, data)) = o2.next_if(|(index, _)| index <= &max_index) {
974            o2_data = Some(data);
975        }
976        let o2_data = o2_data.or(o2_data_latest.take());
977        o2_data_latest.clone_from(&o2_data);
978
979        let mut o3_data = None;
980        while let Some((_, data)) = o3.next_if(|(index, _)| index <= &max_index) {
981            o3_data = Some(data);
982        }
983        let o3_data = o3_data.or(o3_data_latest.take());
984        o3_data_latest.clone_from(&o3_data);
985
986        let mut o4_data = None;
987        while let Some((_, data)) = o4.next_if(|(index, _)| index <= &max_index) {
988            o4_data = Some(data);
989        }
990        let o4_data = o4_data.or(o4_data_latest.take());
991        o4_data_latest.clone_from(&o4_data);
992
993        let mut o5_data = None;
994        while let Some((_, data)) = o5.next_if(|(index, _)| index <= &max_index) {
995            o5_data = Some(data);
996        }
997        let o5_data = o5_data.or(o5_data_latest.take());
998        o5_data_latest.clone_from(&o5_data);
999
1000        let mut o6_data = None;
1001        while let Some((_, data)) = o6.next_if(|(index, _)| index <= &max_index) {
1002            o6_data = Some(data);
1003        }
1004        let o6_data = o6_data.or(o6_data_latest.take());
1005        o6_data_latest.clone_from(&o6_data);
1006
1007        Some((
1008            max_index, r0_data, o0_data, o1_data, o2_data, o3_data, o4_data, o5_data, o6_data,
1009        ))
1010    }
1011}
1012
1013/// Returns a new [`RangeZip1x8`] iterator.
1014///
1015/// The number of elements in a range zip iterator corresponds to the number of elements in the
1016/// shortest of its required iterators (`r0`).
1017///
1018/// Each call to `next` is guaranteed to yield the next value for each required iterator,
1019/// as well as the most recent index amongst all of them.
1020///
1021/// Optional iterators accumulate their state and yield their most recent value (if any),
1022/// each time the required iterators fire.
1023pub fn range_zip_1x8<
1024    Idx,
1025    IR0,
1026    R0,
1027    IO0,
1028    O0,
1029    IO1,
1030    O1,
1031    IO2,
1032    O2,
1033    IO3,
1034    O3,
1035    IO4,
1036    O4,
1037    IO5,
1038    O5,
1039    IO6,
1040    O6,
1041    IO7,
1042    O7,
1043>(
1044    r0: IR0,
1045    o0: IO0,
1046    o1: IO1,
1047    o2: IO2,
1048    o3: IO3,
1049    o4: IO4,
1050    o5: IO5,
1051    o6: IO6,
1052    o7: IO7,
1053) -> RangeZip1x8<
1054    Idx,
1055    IR0::IntoIter,
1056    R0,
1057    IO0::IntoIter,
1058    O0,
1059    IO1::IntoIter,
1060    O1,
1061    IO2::IntoIter,
1062    O2,
1063    IO3::IntoIter,
1064    O3,
1065    IO4::IntoIter,
1066    O4,
1067    IO5::IntoIter,
1068    O5,
1069    IO6::IntoIter,
1070    O6,
1071    IO7::IntoIter,
1072    O7,
1073>
1074where
1075    Idx: std::cmp::Ord,
1076    IR0: IntoIterator<Item = (Idx, R0)>,
1077    IO0: IntoIterator<Item = (Idx, O0)>,
1078    IO1: IntoIterator<Item = (Idx, O1)>,
1079    IO2: IntoIterator<Item = (Idx, O2)>,
1080    IO3: IntoIterator<Item = (Idx, O3)>,
1081    IO4: IntoIterator<Item = (Idx, O4)>,
1082    IO5: IntoIterator<Item = (Idx, O5)>,
1083    IO6: IntoIterator<Item = (Idx, O6)>,
1084    IO7: IntoIterator<Item = (Idx, O7)>,
1085{
1086    RangeZip1x8 {
1087        r0: r0.into_iter(),
1088        o0: o0.into_iter().peekable(),
1089        o1: o1.into_iter().peekable(),
1090        o2: o2.into_iter().peekable(),
1091        o3: o3.into_iter().peekable(),
1092        o4: o4.into_iter().peekable(),
1093        o5: o5.into_iter().peekable(),
1094        o6: o6.into_iter().peekable(),
1095        o7: o7.into_iter().peekable(),
1096
1097        o0_data_latest: None,
1098        o1_data_latest: None,
1099        o2_data_latest: None,
1100        o3_data_latest: None,
1101        o4_data_latest: None,
1102        o5_data_latest: None,
1103        o6_data_latest: None,
1104        o7_data_latest: None,
1105    }
1106}
1107
1108/// Implements a range zip iterator combinator with 2 required iterators and 2 optional
1109/// iterators.
1110///
1111/// See [`range_zip_1x8`] for more information.
1112pub struct RangeZip1x8<
1113    Idx,
1114    IR0,
1115    R0,
1116    IO0,
1117    O0,
1118    IO1,
1119    O1,
1120    IO2,
1121    O2,
1122    IO3,
1123    O3,
1124    IO4,
1125    O4,
1126    IO5,
1127    O5,
1128    IO6,
1129    O6,
1130    IO7,
1131    O7,
1132> where
1133    Idx: std::cmp::Ord,
1134    IR0: Iterator<Item = (Idx, R0)>,
1135    IO0: Iterator<Item = (Idx, O0)>,
1136    IO1: Iterator<Item = (Idx, O1)>,
1137    IO2: Iterator<Item = (Idx, O2)>,
1138    IO3: Iterator<Item = (Idx, O3)>,
1139    IO4: Iterator<Item = (Idx, O4)>,
1140    IO5: Iterator<Item = (Idx, O5)>,
1141    IO6: Iterator<Item = (Idx, O6)>,
1142    IO7: Iterator<Item = (Idx, O7)>,
1143{
1144    r0: IR0,
1145    o0: Peekable<IO0>,
1146    o1: Peekable<IO1>,
1147    o2: Peekable<IO2>,
1148    o3: Peekable<IO3>,
1149    o4: Peekable<IO4>,
1150    o5: Peekable<IO5>,
1151    o6: Peekable<IO6>,
1152    o7: Peekable<IO7>,
1153
1154    o0_data_latest: Option<O0>,
1155    o1_data_latest: Option<O1>,
1156    o2_data_latest: Option<O2>,
1157    o3_data_latest: Option<O3>,
1158    o4_data_latest: Option<O4>,
1159    o5_data_latest: Option<O5>,
1160    o6_data_latest: Option<O6>,
1161    o7_data_latest: Option<O7>,
1162}
1163
1164impl<Idx, IR0, R0, IO0, O0, IO1, O1, IO2, O2, IO3, O3, IO4, O4, IO5, O5, IO6, O6, IO7, O7> Iterator
1165    for RangeZip1x8<
1166        Idx,
1167        IR0,
1168        R0,
1169        IO0,
1170        O0,
1171        IO1,
1172        O1,
1173        IO2,
1174        O2,
1175        IO3,
1176        O3,
1177        IO4,
1178        O4,
1179        IO5,
1180        O5,
1181        IO6,
1182        O6,
1183        IO7,
1184        O7,
1185    >
1186where
1187    Idx: std::cmp::Ord,
1188    IR0: Iterator<Item = (Idx, R0)>,
1189    IO0: Iterator<Item = (Idx, O0)>,
1190    IO1: Iterator<Item = (Idx, O1)>,
1191    IO2: Iterator<Item = (Idx, O2)>,
1192    IO3: Iterator<Item = (Idx, O3)>,
1193    IO4: Iterator<Item = (Idx, O4)>,
1194    IO5: Iterator<Item = (Idx, O5)>,
1195    IO6: Iterator<Item = (Idx, O6)>,
1196    IO7: Iterator<Item = (Idx, O7)>,
1197    O0: Clone,
1198    O1: Clone,
1199    O2: Clone,
1200    O3: Clone,
1201    O4: Clone,
1202    O5: Clone,
1203    O6: Clone,
1204    O7: Clone,
1205{
1206    type Item = (
1207        Idx,
1208        R0,
1209        Option<O0>,
1210        Option<O1>,
1211        Option<O2>,
1212        Option<O3>,
1213        Option<O4>,
1214        Option<O5>,
1215        Option<O6>,
1216        Option<O7>,
1217    );
1218
1219    #[inline]
1220    fn next(&mut self) -> Option<Self::Item> {
1221        let Self {
1222            r0,
1223            o0,
1224            o1,
1225            o2,
1226            o3,
1227            o4,
1228            o5,
1229            o6,
1230            o7,
1231            o0_data_latest,
1232            o1_data_latest,
1233            o2_data_latest,
1234            o3_data_latest,
1235            o4_data_latest,
1236            o5_data_latest,
1237            o6_data_latest,
1238            o7_data_latest,
1239        } = self;
1240
1241        let (r0_index, r0_data) = r0.next()?;
1242
1243        let max_index = [r0_index].into_iter().max()?;
1244
1245        let mut o0_data = None;
1246        while let Some((_, data)) = o0.next_if(|(index, _)| index <= &max_index) {
1247            o0_data = Some(data);
1248        }
1249        let o0_data = o0_data.or(o0_data_latest.take());
1250        o0_data_latest.clone_from(&o0_data);
1251
1252        let mut o1_data = None;
1253        while let Some((_, data)) = o1.next_if(|(index, _)| index <= &max_index) {
1254            o1_data = Some(data);
1255        }
1256        let o1_data = o1_data.or(o1_data_latest.take());
1257        o1_data_latest.clone_from(&o1_data);
1258
1259        let mut o2_data = None;
1260        while let Some((_, data)) = o2.next_if(|(index, _)| index <= &max_index) {
1261            o2_data = Some(data);
1262        }
1263        let o2_data = o2_data.or(o2_data_latest.take());
1264        o2_data_latest.clone_from(&o2_data);
1265
1266        let mut o3_data = None;
1267        while let Some((_, data)) = o3.next_if(|(index, _)| index <= &max_index) {
1268            o3_data = Some(data);
1269        }
1270        let o3_data = o3_data.or(o3_data_latest.take());
1271        o3_data_latest.clone_from(&o3_data);
1272
1273        let mut o4_data = None;
1274        while let Some((_, data)) = o4.next_if(|(index, _)| index <= &max_index) {
1275            o4_data = Some(data);
1276        }
1277        let o4_data = o4_data.or(o4_data_latest.take());
1278        o4_data_latest.clone_from(&o4_data);
1279
1280        let mut o5_data = None;
1281        while let Some((_, data)) = o5.next_if(|(index, _)| index <= &max_index) {
1282            o5_data = Some(data);
1283        }
1284        let o5_data = o5_data.or(o5_data_latest.take());
1285        o5_data_latest.clone_from(&o5_data);
1286
1287        let mut o6_data = None;
1288        while let Some((_, data)) = o6.next_if(|(index, _)| index <= &max_index) {
1289            o6_data = Some(data);
1290        }
1291        let o6_data = o6_data.or(o6_data_latest.take());
1292        o6_data_latest.clone_from(&o6_data);
1293
1294        let mut o7_data = None;
1295        while let Some((_, data)) = o7.next_if(|(index, _)| index <= &max_index) {
1296            o7_data = Some(data);
1297        }
1298        let o7_data = o7_data.or(o7_data_latest.take());
1299        o7_data_latest.clone_from(&o7_data);
1300
1301        Some((
1302            max_index, r0_data, o0_data, o1_data, o2_data, o3_data, o4_data, o5_data, o6_data,
1303            o7_data,
1304        ))
1305    }
1306}
1307
1308/// Returns a new [`RangeZip1x9`] iterator.
1309///
1310/// The number of elements in a range zip iterator corresponds to the number of elements in the
1311/// shortest of its required iterators (`r0`).
1312///
1313/// Each call to `next` is guaranteed to yield the next value for each required iterator,
1314/// as well as the most recent index amongst all of them.
1315///
1316/// Optional iterators accumulate their state and yield their most recent value (if any),
1317/// each time the required iterators fire.
1318pub fn range_zip_1x9<
1319    Idx,
1320    IR0,
1321    R0,
1322    IO0,
1323    O0,
1324    IO1,
1325    O1,
1326    IO2,
1327    O2,
1328    IO3,
1329    O3,
1330    IO4,
1331    O4,
1332    IO5,
1333    O5,
1334    IO6,
1335    O6,
1336    IO7,
1337    O7,
1338    IO8,
1339    O8,
1340>(
1341    r0: IR0,
1342    o0: IO0,
1343    o1: IO1,
1344    o2: IO2,
1345    o3: IO3,
1346    o4: IO4,
1347    o5: IO5,
1348    o6: IO6,
1349    o7: IO7,
1350    o8: IO8,
1351) -> RangeZip1x9<
1352    Idx,
1353    IR0::IntoIter,
1354    R0,
1355    IO0::IntoIter,
1356    O0,
1357    IO1::IntoIter,
1358    O1,
1359    IO2::IntoIter,
1360    O2,
1361    IO3::IntoIter,
1362    O3,
1363    IO4::IntoIter,
1364    O4,
1365    IO5::IntoIter,
1366    O5,
1367    IO6::IntoIter,
1368    O6,
1369    IO7::IntoIter,
1370    O7,
1371    IO8::IntoIter,
1372    O8,
1373>
1374where
1375    Idx: std::cmp::Ord,
1376    IR0: IntoIterator<Item = (Idx, R0)>,
1377    IO0: IntoIterator<Item = (Idx, O0)>,
1378    IO1: IntoIterator<Item = (Idx, O1)>,
1379    IO2: IntoIterator<Item = (Idx, O2)>,
1380    IO3: IntoIterator<Item = (Idx, O3)>,
1381    IO4: IntoIterator<Item = (Idx, O4)>,
1382    IO5: IntoIterator<Item = (Idx, O5)>,
1383    IO6: IntoIterator<Item = (Idx, O6)>,
1384    IO7: IntoIterator<Item = (Idx, O7)>,
1385    IO8: IntoIterator<Item = (Idx, O8)>,
1386{
1387    RangeZip1x9 {
1388        r0: r0.into_iter(),
1389        o0: o0.into_iter().peekable(),
1390        o1: o1.into_iter().peekable(),
1391        o2: o2.into_iter().peekable(),
1392        o3: o3.into_iter().peekable(),
1393        o4: o4.into_iter().peekable(),
1394        o5: o5.into_iter().peekable(),
1395        o6: o6.into_iter().peekable(),
1396        o7: o7.into_iter().peekable(),
1397        o8: o8.into_iter().peekable(),
1398
1399        o0_data_latest: None,
1400        o1_data_latest: None,
1401        o2_data_latest: None,
1402        o3_data_latest: None,
1403        o4_data_latest: None,
1404        o5_data_latest: None,
1405        o6_data_latest: None,
1406        o7_data_latest: None,
1407        o8_data_latest: None,
1408    }
1409}
1410
1411/// Implements a range zip iterator combinator with 2 required iterators and 2 optional
1412/// iterators.
1413///
1414/// See [`range_zip_1x9`] for more information.
1415pub struct RangeZip1x9<
1416    Idx,
1417    IR0,
1418    R0,
1419    IO0,
1420    O0,
1421    IO1,
1422    O1,
1423    IO2,
1424    O2,
1425    IO3,
1426    O3,
1427    IO4,
1428    O4,
1429    IO5,
1430    O5,
1431    IO6,
1432    O6,
1433    IO7,
1434    O7,
1435    IO8,
1436    O8,
1437> where
1438    Idx: std::cmp::Ord,
1439    IR0: Iterator<Item = (Idx, R0)>,
1440    IO0: Iterator<Item = (Idx, O0)>,
1441    IO1: Iterator<Item = (Idx, O1)>,
1442    IO2: Iterator<Item = (Idx, O2)>,
1443    IO3: Iterator<Item = (Idx, O3)>,
1444    IO4: Iterator<Item = (Idx, O4)>,
1445    IO5: Iterator<Item = (Idx, O5)>,
1446    IO6: Iterator<Item = (Idx, O6)>,
1447    IO7: Iterator<Item = (Idx, O7)>,
1448    IO8: Iterator<Item = (Idx, O8)>,
1449{
1450    r0: IR0,
1451    o0: Peekable<IO0>,
1452    o1: Peekable<IO1>,
1453    o2: Peekable<IO2>,
1454    o3: Peekable<IO3>,
1455    o4: Peekable<IO4>,
1456    o5: Peekable<IO5>,
1457    o6: Peekable<IO6>,
1458    o7: Peekable<IO7>,
1459    o8: Peekable<IO8>,
1460
1461    o0_data_latest: Option<O0>,
1462    o1_data_latest: Option<O1>,
1463    o2_data_latest: Option<O2>,
1464    o3_data_latest: Option<O3>,
1465    o4_data_latest: Option<O4>,
1466    o5_data_latest: Option<O5>,
1467    o6_data_latest: Option<O6>,
1468    o7_data_latest: Option<O7>,
1469    o8_data_latest: Option<O8>,
1470}
1471
1472impl<Idx, IR0, R0, IO0, O0, IO1, O1, IO2, O2, IO3, O3, IO4, O4, IO5, O5, IO6, O6, IO7, O7, IO8, O8>
1473    Iterator
1474    for RangeZip1x9<
1475        Idx,
1476        IR0,
1477        R0,
1478        IO0,
1479        O0,
1480        IO1,
1481        O1,
1482        IO2,
1483        O2,
1484        IO3,
1485        O3,
1486        IO4,
1487        O4,
1488        IO5,
1489        O5,
1490        IO6,
1491        O6,
1492        IO7,
1493        O7,
1494        IO8,
1495        O8,
1496    >
1497where
1498    Idx: std::cmp::Ord,
1499    IR0: Iterator<Item = (Idx, R0)>,
1500    IO0: Iterator<Item = (Idx, O0)>,
1501    IO1: Iterator<Item = (Idx, O1)>,
1502    IO2: Iterator<Item = (Idx, O2)>,
1503    IO3: Iterator<Item = (Idx, O3)>,
1504    IO4: Iterator<Item = (Idx, O4)>,
1505    IO5: Iterator<Item = (Idx, O5)>,
1506    IO6: Iterator<Item = (Idx, O6)>,
1507    IO7: Iterator<Item = (Idx, O7)>,
1508    IO8: Iterator<Item = (Idx, O8)>,
1509    O0: Clone,
1510    O1: Clone,
1511    O2: Clone,
1512    O3: Clone,
1513    O4: Clone,
1514    O5: Clone,
1515    O6: Clone,
1516    O7: Clone,
1517    O8: Clone,
1518{
1519    type Item = (
1520        Idx,
1521        R0,
1522        Option<O0>,
1523        Option<O1>,
1524        Option<O2>,
1525        Option<O3>,
1526        Option<O4>,
1527        Option<O5>,
1528        Option<O6>,
1529        Option<O7>,
1530        Option<O8>,
1531    );
1532
1533    #[inline]
1534    fn next(&mut self) -> Option<Self::Item> {
1535        let Self {
1536            r0,
1537            o0,
1538            o1,
1539            o2,
1540            o3,
1541            o4,
1542            o5,
1543            o6,
1544            o7,
1545            o8,
1546            o0_data_latest,
1547            o1_data_latest,
1548            o2_data_latest,
1549            o3_data_latest,
1550            o4_data_latest,
1551            o5_data_latest,
1552            o6_data_latest,
1553            o7_data_latest,
1554            o8_data_latest,
1555        } = self;
1556
1557        let (r0_index, r0_data) = r0.next()?;
1558
1559        let max_index = [r0_index].into_iter().max()?;
1560
1561        let mut o0_data = None;
1562        while let Some((_, data)) = o0.next_if(|(index, _)| index <= &max_index) {
1563            o0_data = Some(data);
1564        }
1565        let o0_data = o0_data.or(o0_data_latest.take());
1566        o0_data_latest.clone_from(&o0_data);
1567
1568        let mut o1_data = None;
1569        while let Some((_, data)) = o1.next_if(|(index, _)| index <= &max_index) {
1570            o1_data = Some(data);
1571        }
1572        let o1_data = o1_data.or(o1_data_latest.take());
1573        o1_data_latest.clone_from(&o1_data);
1574
1575        let mut o2_data = None;
1576        while let Some((_, data)) = o2.next_if(|(index, _)| index <= &max_index) {
1577            o2_data = Some(data);
1578        }
1579        let o2_data = o2_data.or(o2_data_latest.take());
1580        o2_data_latest.clone_from(&o2_data);
1581
1582        let mut o3_data = None;
1583        while let Some((_, data)) = o3.next_if(|(index, _)| index <= &max_index) {
1584            o3_data = Some(data);
1585        }
1586        let o3_data = o3_data.or(o3_data_latest.take());
1587        o3_data_latest.clone_from(&o3_data);
1588
1589        let mut o4_data = None;
1590        while let Some((_, data)) = o4.next_if(|(index, _)| index <= &max_index) {
1591            o4_data = Some(data);
1592        }
1593        let o4_data = o4_data.or(o4_data_latest.take());
1594        o4_data_latest.clone_from(&o4_data);
1595
1596        let mut o5_data = None;
1597        while let Some((_, data)) = o5.next_if(|(index, _)| index <= &max_index) {
1598            o5_data = Some(data);
1599        }
1600        let o5_data = o5_data.or(o5_data_latest.take());
1601        o5_data_latest.clone_from(&o5_data);
1602
1603        let mut o6_data = None;
1604        while let Some((_, data)) = o6.next_if(|(index, _)| index <= &max_index) {
1605            o6_data = Some(data);
1606        }
1607        let o6_data = o6_data.or(o6_data_latest.take());
1608        o6_data_latest.clone_from(&o6_data);
1609
1610        let mut o7_data = None;
1611        while let Some((_, data)) = o7.next_if(|(index, _)| index <= &max_index) {
1612            o7_data = Some(data);
1613        }
1614        let o7_data = o7_data.or(o7_data_latest.take());
1615        o7_data_latest.clone_from(&o7_data);
1616
1617        let mut o8_data = None;
1618        while let Some((_, data)) = o8.next_if(|(index, _)| index <= &max_index) {
1619            o8_data = Some(data);
1620        }
1621        let o8_data = o8_data.or(o8_data_latest.take());
1622        o8_data_latest.clone_from(&o8_data);
1623
1624        Some((
1625            max_index, r0_data, o0_data, o1_data, o2_data, o3_data, o4_data, o5_data, o6_data,
1626            o7_data, o8_data,
1627        ))
1628    }
1629}
1630
1631/// Returns a new [`RangeZip2x1`] iterator.
1632///
1633/// The number of elements in a range zip iterator corresponds to the number of elements in the
1634/// shortest of its required iterators (`r0`, `r1`).
1635///
1636/// Each call to `next` is guaranteed to yield the next value for each required iterator,
1637/// as well as the most recent index amongst all of them.
1638///
1639/// Optional iterators accumulate their state and yield their most recent value (if any),
1640/// each time the required iterators fire.
1641pub fn range_zip_2x1<Idx, IR0, R0, IR1, R1, IO0, O0>(
1642    r0: IR0,
1643    r1: IR1,
1644    o0: IO0,
1645) -> RangeZip2x1<Idx, IR0::IntoIter, R0, IR1::IntoIter, R1, IO0::IntoIter, O0>
1646where
1647    Idx: std::cmp::Ord,
1648    IR0: IntoIterator<Item = (Idx, R0)>,
1649    IR1: IntoIterator<Item = (Idx, R1)>,
1650    IO0: IntoIterator<Item = (Idx, O0)>,
1651{
1652    RangeZip2x1 {
1653        r0: r0.into_iter(),
1654        r1: r1.into_iter(),
1655        o0: o0.into_iter().peekable(),
1656
1657        o0_data_latest: None,
1658    }
1659}
1660
1661/// Implements a range zip iterator combinator with 2 required iterators and 2 optional
1662/// iterators.
1663///
1664/// See [`range_zip_2x1`] for more information.
1665pub struct RangeZip2x1<Idx, IR0, R0, IR1, R1, IO0, O0>
1666where
1667    Idx: std::cmp::Ord,
1668    IR0: Iterator<Item = (Idx, R0)>,
1669    IR1: Iterator<Item = (Idx, R1)>,
1670    IO0: Iterator<Item = (Idx, O0)>,
1671{
1672    r0: IR0,
1673    r1: IR1,
1674    o0: Peekable<IO0>,
1675
1676    o0_data_latest: Option<O0>,
1677}
1678
1679impl<Idx, IR0, R0, IR1, R1, IO0, O0> Iterator for RangeZip2x1<Idx, IR0, R0, IR1, R1, IO0, O0>
1680where
1681    Idx: std::cmp::Ord,
1682    IR0: Iterator<Item = (Idx, R0)>,
1683    IR1: Iterator<Item = (Idx, R1)>,
1684    IO0: Iterator<Item = (Idx, O0)>,
1685    O0: Clone,
1686{
1687    type Item = (Idx, R0, R1, Option<O0>);
1688
1689    #[inline]
1690    fn next(&mut self) -> Option<Self::Item> {
1691        let Self {
1692            r0,
1693            r1,
1694            o0,
1695            o0_data_latest,
1696        } = self;
1697
1698        let (r0_index, r0_data) = r0.next()?;
1699        let (r1_index, r1_data) = r1.next()?;
1700
1701        let max_index = [r0_index, r1_index].into_iter().max()?;
1702
1703        let mut o0_data = None;
1704        while let Some((_, data)) = o0.next_if(|(index, _)| index <= &max_index) {
1705            o0_data = Some(data);
1706        }
1707        let o0_data = o0_data.or(o0_data_latest.take());
1708        o0_data_latest.clone_from(&o0_data);
1709
1710        Some((max_index, r0_data, r1_data, o0_data))
1711    }
1712}
1713
1714/// Returns a new [`RangeZip2x2`] iterator.
1715///
1716/// The number of elements in a range zip iterator corresponds to the number of elements in the
1717/// shortest of its required iterators (`r0`, `r1`).
1718///
1719/// Each call to `next` is guaranteed to yield the next value for each required iterator,
1720/// as well as the most recent index amongst all of them.
1721///
1722/// Optional iterators accumulate their state and yield their most recent value (if any),
1723/// each time the required iterators fire.
1724pub fn range_zip_2x2<Idx, IR0, R0, IR1, R1, IO0, O0, IO1, O1>(
1725    r0: IR0,
1726    r1: IR1,
1727    o0: IO0,
1728    o1: IO1,
1729) -> RangeZip2x2<Idx, IR0::IntoIter, R0, IR1::IntoIter, R1, IO0::IntoIter, O0, IO1::IntoIter, O1>
1730where
1731    Idx: std::cmp::Ord,
1732    IR0: IntoIterator<Item = (Idx, R0)>,
1733    IR1: IntoIterator<Item = (Idx, R1)>,
1734    IO0: IntoIterator<Item = (Idx, O0)>,
1735    IO1: IntoIterator<Item = (Idx, O1)>,
1736{
1737    RangeZip2x2 {
1738        r0: r0.into_iter(),
1739        r1: r1.into_iter(),
1740        o0: o0.into_iter().peekable(),
1741        o1: o1.into_iter().peekable(),
1742
1743        o0_data_latest: None,
1744        o1_data_latest: None,
1745    }
1746}
1747
1748/// Implements a range zip iterator combinator with 2 required iterators and 2 optional
1749/// iterators.
1750///
1751/// See [`range_zip_2x2`] for more information.
1752pub struct RangeZip2x2<Idx, IR0, R0, IR1, R1, IO0, O0, IO1, O1>
1753where
1754    Idx: std::cmp::Ord,
1755    IR0: Iterator<Item = (Idx, R0)>,
1756    IR1: Iterator<Item = (Idx, R1)>,
1757    IO0: Iterator<Item = (Idx, O0)>,
1758    IO1: Iterator<Item = (Idx, O1)>,
1759{
1760    r0: IR0,
1761    r1: IR1,
1762    o0: Peekable<IO0>,
1763    o1: Peekable<IO1>,
1764
1765    o0_data_latest: Option<O0>,
1766    o1_data_latest: Option<O1>,
1767}
1768
1769impl<Idx, IR0, R0, IR1, R1, IO0, O0, IO1, O1> Iterator
1770    for RangeZip2x2<Idx, IR0, R0, IR1, R1, IO0, O0, IO1, O1>
1771where
1772    Idx: std::cmp::Ord,
1773    IR0: Iterator<Item = (Idx, R0)>,
1774    IR1: Iterator<Item = (Idx, R1)>,
1775    IO0: Iterator<Item = (Idx, O0)>,
1776    IO1: Iterator<Item = (Idx, O1)>,
1777    O0: Clone,
1778    O1: Clone,
1779{
1780    type Item = (Idx, R0, R1, Option<O0>, Option<O1>);
1781
1782    #[inline]
1783    fn next(&mut self) -> Option<Self::Item> {
1784        let Self {
1785            r0,
1786            r1,
1787            o0,
1788            o1,
1789            o0_data_latest,
1790            o1_data_latest,
1791        } = self;
1792
1793        let (r0_index, r0_data) = r0.next()?;
1794        let (r1_index, r1_data) = r1.next()?;
1795
1796        let max_index = [r0_index, r1_index].into_iter().max()?;
1797
1798        let mut o0_data = None;
1799        while let Some((_, data)) = o0.next_if(|(index, _)| index <= &max_index) {
1800            o0_data = Some(data);
1801        }
1802        let o0_data = o0_data.or(o0_data_latest.take());
1803        o0_data_latest.clone_from(&o0_data);
1804
1805        let mut o1_data = None;
1806        while let Some((_, data)) = o1.next_if(|(index, _)| index <= &max_index) {
1807            o1_data = Some(data);
1808        }
1809        let o1_data = o1_data.or(o1_data_latest.take());
1810        o1_data_latest.clone_from(&o1_data);
1811
1812        Some((max_index, r0_data, r1_data, o0_data, o1_data))
1813    }
1814}
1815
1816/// Returns a new [`RangeZip2x3`] iterator.
1817///
1818/// The number of elements in a range zip iterator corresponds to the number of elements in the
1819/// shortest of its required iterators (`r0`, `r1`).
1820///
1821/// Each call to `next` is guaranteed to yield the next value for each required iterator,
1822/// as well as the most recent index amongst all of them.
1823///
1824/// Optional iterators accumulate their state and yield their most recent value (if any),
1825/// each time the required iterators fire.
1826pub fn range_zip_2x3<Idx, IR0, R0, IR1, R1, IO0, O0, IO1, O1, IO2, O2>(
1827    r0: IR0,
1828    r1: IR1,
1829    o0: IO0,
1830    o1: IO1,
1831    o2: IO2,
1832) -> RangeZip2x3<
1833    Idx,
1834    IR0::IntoIter,
1835    R0,
1836    IR1::IntoIter,
1837    R1,
1838    IO0::IntoIter,
1839    O0,
1840    IO1::IntoIter,
1841    O1,
1842    IO2::IntoIter,
1843    O2,
1844>
1845where
1846    Idx: std::cmp::Ord,
1847    IR0: IntoIterator<Item = (Idx, R0)>,
1848    IR1: IntoIterator<Item = (Idx, R1)>,
1849    IO0: IntoIterator<Item = (Idx, O0)>,
1850    IO1: IntoIterator<Item = (Idx, O1)>,
1851    IO2: IntoIterator<Item = (Idx, O2)>,
1852{
1853    RangeZip2x3 {
1854        r0: r0.into_iter(),
1855        r1: r1.into_iter(),
1856        o0: o0.into_iter().peekable(),
1857        o1: o1.into_iter().peekable(),
1858        o2: o2.into_iter().peekable(),
1859
1860        o0_data_latest: None,
1861        o1_data_latest: None,
1862        o2_data_latest: None,
1863    }
1864}
1865
1866/// Implements a range zip iterator combinator with 2 required iterators and 2 optional
1867/// iterators.
1868///
1869/// See [`range_zip_2x3`] for more information.
1870pub struct RangeZip2x3<Idx, IR0, R0, IR1, R1, IO0, O0, IO1, O1, IO2, O2>
1871where
1872    Idx: std::cmp::Ord,
1873    IR0: Iterator<Item = (Idx, R0)>,
1874    IR1: Iterator<Item = (Idx, R1)>,
1875    IO0: Iterator<Item = (Idx, O0)>,
1876    IO1: Iterator<Item = (Idx, O1)>,
1877    IO2: Iterator<Item = (Idx, O2)>,
1878{
1879    r0: IR0,
1880    r1: IR1,
1881    o0: Peekable<IO0>,
1882    o1: Peekable<IO1>,
1883    o2: Peekable<IO2>,
1884
1885    o0_data_latest: Option<O0>,
1886    o1_data_latest: Option<O1>,
1887    o2_data_latest: Option<O2>,
1888}
1889
1890impl<Idx, IR0, R0, IR1, R1, IO0, O0, IO1, O1, IO2, O2> Iterator
1891    for RangeZip2x3<Idx, IR0, R0, IR1, R1, IO0, O0, IO1, O1, IO2, O2>
1892where
1893    Idx: std::cmp::Ord,
1894    IR0: Iterator<Item = (Idx, R0)>,
1895    IR1: Iterator<Item = (Idx, R1)>,
1896    IO0: Iterator<Item = (Idx, O0)>,
1897    IO1: Iterator<Item = (Idx, O1)>,
1898    IO2: Iterator<Item = (Idx, O2)>,
1899    O0: Clone,
1900    O1: Clone,
1901    O2: Clone,
1902{
1903    type Item = (Idx, R0, R1, Option<O0>, Option<O1>, Option<O2>);
1904
1905    #[inline]
1906    fn next(&mut self) -> Option<Self::Item> {
1907        let Self {
1908            r0,
1909            r1,
1910            o0,
1911            o1,
1912            o2,
1913            o0_data_latest,
1914            o1_data_latest,
1915            o2_data_latest,
1916        } = self;
1917
1918        let (r0_index, r0_data) = r0.next()?;
1919        let (r1_index, r1_data) = r1.next()?;
1920
1921        let max_index = [r0_index, r1_index].into_iter().max()?;
1922
1923        let mut o0_data = None;
1924        while let Some((_, data)) = o0.next_if(|(index, _)| index <= &max_index) {
1925            o0_data = Some(data);
1926        }
1927        let o0_data = o0_data.or(o0_data_latest.take());
1928        o0_data_latest.clone_from(&o0_data);
1929
1930        let mut o1_data = None;
1931        while let Some((_, data)) = o1.next_if(|(index, _)| index <= &max_index) {
1932            o1_data = Some(data);
1933        }
1934        let o1_data = o1_data.or(o1_data_latest.take());
1935        o1_data_latest.clone_from(&o1_data);
1936
1937        let mut o2_data = None;
1938        while let Some((_, data)) = o2.next_if(|(index, _)| index <= &max_index) {
1939            o2_data = Some(data);
1940        }
1941        let o2_data = o2_data.or(o2_data_latest.take());
1942        o2_data_latest.clone_from(&o2_data);
1943
1944        Some((max_index, r0_data, r1_data, o0_data, o1_data, o2_data))
1945    }
1946}
1947
1948/// Returns a new [`RangeZip2x4`] iterator.
1949///
1950/// The number of elements in a range zip iterator corresponds to the number of elements in the
1951/// shortest of its required iterators (`r0`, `r1`).
1952///
1953/// Each call to `next` is guaranteed to yield the next value for each required iterator,
1954/// as well as the most recent index amongst all of them.
1955///
1956/// Optional iterators accumulate their state and yield their most recent value (if any),
1957/// each time the required iterators fire.
1958pub fn range_zip_2x4<Idx, IR0, R0, IR1, R1, IO0, O0, IO1, O1, IO2, O2, IO3, O3>(
1959    r0: IR0,
1960    r1: IR1,
1961    o0: IO0,
1962    o1: IO1,
1963    o2: IO2,
1964    o3: IO3,
1965) -> RangeZip2x4<
1966    Idx,
1967    IR0::IntoIter,
1968    R0,
1969    IR1::IntoIter,
1970    R1,
1971    IO0::IntoIter,
1972    O0,
1973    IO1::IntoIter,
1974    O1,
1975    IO2::IntoIter,
1976    O2,
1977    IO3::IntoIter,
1978    O3,
1979>
1980where
1981    Idx: std::cmp::Ord,
1982    IR0: IntoIterator<Item = (Idx, R0)>,
1983    IR1: IntoIterator<Item = (Idx, R1)>,
1984    IO0: IntoIterator<Item = (Idx, O0)>,
1985    IO1: IntoIterator<Item = (Idx, O1)>,
1986    IO2: IntoIterator<Item = (Idx, O2)>,
1987    IO3: IntoIterator<Item = (Idx, O3)>,
1988{
1989    RangeZip2x4 {
1990        r0: r0.into_iter(),
1991        r1: r1.into_iter(),
1992        o0: o0.into_iter().peekable(),
1993        o1: o1.into_iter().peekable(),
1994        o2: o2.into_iter().peekable(),
1995        o3: o3.into_iter().peekable(),
1996
1997        o0_data_latest: None,
1998        o1_data_latest: None,
1999        o2_data_latest: None,
2000        o3_data_latest: None,
2001    }
2002}
2003
2004/// Implements a range zip iterator combinator with 2 required iterators and 2 optional
2005/// iterators.
2006///
2007/// See [`range_zip_2x4`] for more information.
2008pub struct RangeZip2x4<Idx, IR0, R0, IR1, R1, IO0, O0, IO1, O1, IO2, O2, IO3, O3>
2009where
2010    Idx: std::cmp::Ord,
2011    IR0: Iterator<Item = (Idx, R0)>,
2012    IR1: Iterator<Item = (Idx, R1)>,
2013    IO0: Iterator<Item = (Idx, O0)>,
2014    IO1: Iterator<Item = (Idx, O1)>,
2015    IO2: Iterator<Item = (Idx, O2)>,
2016    IO3: Iterator<Item = (Idx, O3)>,
2017{
2018    r0: IR0,
2019    r1: IR1,
2020    o0: Peekable<IO0>,
2021    o1: Peekable<IO1>,
2022    o2: Peekable<IO2>,
2023    o3: Peekable<IO3>,
2024
2025    o0_data_latest: Option<O0>,
2026    o1_data_latest: Option<O1>,
2027    o2_data_latest: Option<O2>,
2028    o3_data_latest: Option<O3>,
2029}
2030
2031impl<Idx, IR0, R0, IR1, R1, IO0, O0, IO1, O1, IO2, O2, IO3, O3> Iterator
2032    for RangeZip2x4<Idx, IR0, R0, IR1, R1, IO0, O0, IO1, O1, IO2, O2, IO3, O3>
2033where
2034    Idx: std::cmp::Ord,
2035    IR0: Iterator<Item = (Idx, R0)>,
2036    IR1: Iterator<Item = (Idx, R1)>,
2037    IO0: Iterator<Item = (Idx, O0)>,
2038    IO1: Iterator<Item = (Idx, O1)>,
2039    IO2: Iterator<Item = (Idx, O2)>,
2040    IO3: Iterator<Item = (Idx, O3)>,
2041    O0: Clone,
2042    O1: Clone,
2043    O2: Clone,
2044    O3: Clone,
2045{
2046    type Item = (Idx, R0, R1, Option<O0>, Option<O1>, Option<O2>, Option<O3>);
2047
2048    #[inline]
2049    fn next(&mut self) -> Option<Self::Item> {
2050        let Self {
2051            r0,
2052            r1,
2053            o0,
2054            o1,
2055            o2,
2056            o3,
2057            o0_data_latest,
2058            o1_data_latest,
2059            o2_data_latest,
2060            o3_data_latest,
2061        } = self;
2062
2063        let (r0_index, r0_data) = r0.next()?;
2064        let (r1_index, r1_data) = r1.next()?;
2065
2066        let max_index = [r0_index, r1_index].into_iter().max()?;
2067
2068        let mut o0_data = None;
2069        while let Some((_, data)) = o0.next_if(|(index, _)| index <= &max_index) {
2070            o0_data = Some(data);
2071        }
2072        let o0_data = o0_data.or(o0_data_latest.take());
2073        o0_data_latest.clone_from(&o0_data);
2074
2075        let mut o1_data = None;
2076        while let Some((_, data)) = o1.next_if(|(index, _)| index <= &max_index) {
2077            o1_data = Some(data);
2078        }
2079        let o1_data = o1_data.or(o1_data_latest.take());
2080        o1_data_latest.clone_from(&o1_data);
2081
2082        let mut o2_data = None;
2083        while let Some((_, data)) = o2.next_if(|(index, _)| index <= &max_index) {
2084            o2_data = Some(data);
2085        }
2086        let o2_data = o2_data.or(o2_data_latest.take());
2087        o2_data_latest.clone_from(&o2_data);
2088
2089        let mut o3_data = None;
2090        while let Some((_, data)) = o3.next_if(|(index, _)| index <= &max_index) {
2091            o3_data = Some(data);
2092        }
2093        let o3_data = o3_data.or(o3_data_latest.take());
2094        o3_data_latest.clone_from(&o3_data);
2095
2096        Some((
2097            max_index, r0_data, r1_data, o0_data, o1_data, o2_data, o3_data,
2098        ))
2099    }
2100}
2101
2102/// Returns a new [`RangeZip2x5`] iterator.
2103///
2104/// The number of elements in a range zip iterator corresponds to the number of elements in the
2105/// shortest of its required iterators (`r0`, `r1`).
2106///
2107/// Each call to `next` is guaranteed to yield the next value for each required iterator,
2108/// as well as the most recent index amongst all of them.
2109///
2110/// Optional iterators accumulate their state and yield their most recent value (if any),
2111/// each time the required iterators fire.
2112pub fn range_zip_2x5<Idx, IR0, R0, IR1, R1, IO0, O0, IO1, O1, IO2, O2, IO3, O3, IO4, O4>(
2113    r0: IR0,
2114    r1: IR1,
2115    o0: IO0,
2116    o1: IO1,
2117    o2: IO2,
2118    o3: IO3,
2119    o4: IO4,
2120) -> RangeZip2x5<
2121    Idx,
2122    IR0::IntoIter,
2123    R0,
2124    IR1::IntoIter,
2125    R1,
2126    IO0::IntoIter,
2127    O0,
2128    IO1::IntoIter,
2129    O1,
2130    IO2::IntoIter,
2131    O2,
2132    IO3::IntoIter,
2133    O3,
2134    IO4::IntoIter,
2135    O4,
2136>
2137where
2138    Idx: std::cmp::Ord,
2139    IR0: IntoIterator<Item = (Idx, R0)>,
2140    IR1: IntoIterator<Item = (Idx, R1)>,
2141    IO0: IntoIterator<Item = (Idx, O0)>,
2142    IO1: IntoIterator<Item = (Idx, O1)>,
2143    IO2: IntoIterator<Item = (Idx, O2)>,
2144    IO3: IntoIterator<Item = (Idx, O3)>,
2145    IO4: IntoIterator<Item = (Idx, O4)>,
2146{
2147    RangeZip2x5 {
2148        r0: r0.into_iter(),
2149        r1: r1.into_iter(),
2150        o0: o0.into_iter().peekable(),
2151        o1: o1.into_iter().peekable(),
2152        o2: o2.into_iter().peekable(),
2153        o3: o3.into_iter().peekable(),
2154        o4: o4.into_iter().peekable(),
2155
2156        o0_data_latest: None,
2157        o1_data_latest: None,
2158        o2_data_latest: None,
2159        o3_data_latest: None,
2160        o4_data_latest: None,
2161    }
2162}
2163
2164/// Implements a range zip iterator combinator with 2 required iterators and 2 optional
2165/// iterators.
2166///
2167/// See [`range_zip_2x5`] for more information.
2168pub struct RangeZip2x5<Idx, IR0, R0, IR1, R1, IO0, O0, IO1, O1, IO2, O2, IO3, O3, IO4, O4>
2169where
2170    Idx: std::cmp::Ord,
2171    IR0: Iterator<Item = (Idx, R0)>,
2172    IR1: Iterator<Item = (Idx, R1)>,
2173    IO0: Iterator<Item = (Idx, O0)>,
2174    IO1: Iterator<Item = (Idx, O1)>,
2175    IO2: Iterator<Item = (Idx, O2)>,
2176    IO3: Iterator<Item = (Idx, O3)>,
2177    IO4: Iterator<Item = (Idx, O4)>,
2178{
2179    r0: IR0,
2180    r1: IR1,
2181    o0: Peekable<IO0>,
2182    o1: Peekable<IO1>,
2183    o2: Peekable<IO2>,
2184    o3: Peekable<IO3>,
2185    o4: Peekable<IO4>,
2186
2187    o0_data_latest: Option<O0>,
2188    o1_data_latest: Option<O1>,
2189    o2_data_latest: Option<O2>,
2190    o3_data_latest: Option<O3>,
2191    o4_data_latest: Option<O4>,
2192}
2193
2194impl<Idx, IR0, R0, IR1, R1, IO0, O0, IO1, O1, IO2, O2, IO3, O3, IO4, O4> Iterator
2195    for RangeZip2x5<Idx, IR0, R0, IR1, R1, IO0, O0, IO1, O1, IO2, O2, IO3, O3, IO4, O4>
2196where
2197    Idx: std::cmp::Ord,
2198    IR0: Iterator<Item = (Idx, R0)>,
2199    IR1: Iterator<Item = (Idx, R1)>,
2200    IO0: Iterator<Item = (Idx, O0)>,
2201    IO1: Iterator<Item = (Idx, O1)>,
2202    IO2: Iterator<Item = (Idx, O2)>,
2203    IO3: Iterator<Item = (Idx, O3)>,
2204    IO4: Iterator<Item = (Idx, O4)>,
2205    O0: Clone,
2206    O1: Clone,
2207    O2: Clone,
2208    O3: Clone,
2209    O4: Clone,
2210{
2211    type Item = (
2212        Idx,
2213        R0,
2214        R1,
2215        Option<O0>,
2216        Option<O1>,
2217        Option<O2>,
2218        Option<O3>,
2219        Option<O4>,
2220    );
2221
2222    #[inline]
2223    fn next(&mut self) -> Option<Self::Item> {
2224        let Self {
2225            r0,
2226            r1,
2227            o0,
2228            o1,
2229            o2,
2230            o3,
2231            o4,
2232            o0_data_latest,
2233            o1_data_latest,
2234            o2_data_latest,
2235            o3_data_latest,
2236            o4_data_latest,
2237        } = self;
2238
2239        let (r0_index, r0_data) = r0.next()?;
2240        let (r1_index, r1_data) = r1.next()?;
2241
2242        let max_index = [r0_index, r1_index].into_iter().max()?;
2243
2244        let mut o0_data = None;
2245        while let Some((_, data)) = o0.next_if(|(index, _)| index <= &max_index) {
2246            o0_data = Some(data);
2247        }
2248        let o0_data = o0_data.or(o0_data_latest.take());
2249        o0_data_latest.clone_from(&o0_data);
2250
2251        let mut o1_data = None;
2252        while let Some((_, data)) = o1.next_if(|(index, _)| index <= &max_index) {
2253            o1_data = Some(data);
2254        }
2255        let o1_data = o1_data.or(o1_data_latest.take());
2256        o1_data_latest.clone_from(&o1_data);
2257
2258        let mut o2_data = None;
2259        while let Some((_, data)) = o2.next_if(|(index, _)| index <= &max_index) {
2260            o2_data = Some(data);
2261        }
2262        let o2_data = o2_data.or(o2_data_latest.take());
2263        o2_data_latest.clone_from(&o2_data);
2264
2265        let mut o3_data = None;
2266        while let Some((_, data)) = o3.next_if(|(index, _)| index <= &max_index) {
2267            o3_data = Some(data);
2268        }
2269        let o3_data = o3_data.or(o3_data_latest.take());
2270        o3_data_latest.clone_from(&o3_data);
2271
2272        let mut o4_data = None;
2273        while let Some((_, data)) = o4.next_if(|(index, _)| index <= &max_index) {
2274            o4_data = Some(data);
2275        }
2276        let o4_data = o4_data.or(o4_data_latest.take());
2277        o4_data_latest.clone_from(&o4_data);
2278
2279        Some((
2280            max_index, r0_data, r1_data, o0_data, o1_data, o2_data, o3_data, o4_data,
2281        ))
2282    }
2283}
2284
2285/// Returns a new [`RangeZip2x6`] iterator.
2286///
2287/// The number of elements in a range zip iterator corresponds to the number of elements in the
2288/// shortest of its required iterators (`r0`, `r1`).
2289///
2290/// Each call to `next` is guaranteed to yield the next value for each required iterator,
2291/// as well as the most recent index amongst all of them.
2292///
2293/// Optional iterators accumulate their state and yield their most recent value (if any),
2294/// each time the required iterators fire.
2295pub fn range_zip_2x6<Idx, IR0, R0, IR1, R1, IO0, O0, IO1, O1, IO2, O2, IO3, O3, IO4, O4, IO5, O5>(
2296    r0: IR0,
2297    r1: IR1,
2298    o0: IO0,
2299    o1: IO1,
2300    o2: IO2,
2301    o3: IO3,
2302    o4: IO4,
2303    o5: IO5,
2304) -> RangeZip2x6<
2305    Idx,
2306    IR0::IntoIter,
2307    R0,
2308    IR1::IntoIter,
2309    R1,
2310    IO0::IntoIter,
2311    O0,
2312    IO1::IntoIter,
2313    O1,
2314    IO2::IntoIter,
2315    O2,
2316    IO3::IntoIter,
2317    O3,
2318    IO4::IntoIter,
2319    O4,
2320    IO5::IntoIter,
2321    O5,
2322>
2323where
2324    Idx: std::cmp::Ord,
2325    IR0: IntoIterator<Item = (Idx, R0)>,
2326    IR1: IntoIterator<Item = (Idx, R1)>,
2327    IO0: IntoIterator<Item = (Idx, O0)>,
2328    IO1: IntoIterator<Item = (Idx, O1)>,
2329    IO2: IntoIterator<Item = (Idx, O2)>,
2330    IO3: IntoIterator<Item = (Idx, O3)>,
2331    IO4: IntoIterator<Item = (Idx, O4)>,
2332    IO5: IntoIterator<Item = (Idx, O5)>,
2333{
2334    RangeZip2x6 {
2335        r0: r0.into_iter(),
2336        r1: r1.into_iter(),
2337        o0: o0.into_iter().peekable(),
2338        o1: o1.into_iter().peekable(),
2339        o2: o2.into_iter().peekable(),
2340        o3: o3.into_iter().peekable(),
2341        o4: o4.into_iter().peekable(),
2342        o5: o5.into_iter().peekable(),
2343
2344        o0_data_latest: None,
2345        o1_data_latest: None,
2346        o2_data_latest: None,
2347        o3_data_latest: None,
2348        o4_data_latest: None,
2349        o5_data_latest: None,
2350    }
2351}
2352
2353/// Implements a range zip iterator combinator with 2 required iterators and 2 optional
2354/// iterators.
2355///
2356/// See [`range_zip_2x6`] for more information.
2357pub struct RangeZip2x6<Idx, IR0, R0, IR1, R1, IO0, O0, IO1, O1, IO2, O2, IO3, O3, IO4, O4, IO5, O5>
2358where
2359    Idx: std::cmp::Ord,
2360    IR0: Iterator<Item = (Idx, R0)>,
2361    IR1: Iterator<Item = (Idx, R1)>,
2362    IO0: Iterator<Item = (Idx, O0)>,
2363    IO1: Iterator<Item = (Idx, O1)>,
2364    IO2: Iterator<Item = (Idx, O2)>,
2365    IO3: Iterator<Item = (Idx, O3)>,
2366    IO4: Iterator<Item = (Idx, O4)>,
2367    IO5: Iterator<Item = (Idx, O5)>,
2368{
2369    r0: IR0,
2370    r1: IR1,
2371    o0: Peekable<IO0>,
2372    o1: Peekable<IO1>,
2373    o2: Peekable<IO2>,
2374    o3: Peekable<IO3>,
2375    o4: Peekable<IO4>,
2376    o5: Peekable<IO5>,
2377
2378    o0_data_latest: Option<O0>,
2379    o1_data_latest: Option<O1>,
2380    o2_data_latest: Option<O2>,
2381    o3_data_latest: Option<O3>,
2382    o4_data_latest: Option<O4>,
2383    o5_data_latest: Option<O5>,
2384}
2385
2386impl<Idx, IR0, R0, IR1, R1, IO0, O0, IO1, O1, IO2, O2, IO3, O3, IO4, O4, IO5, O5> Iterator
2387    for RangeZip2x6<Idx, IR0, R0, IR1, R1, IO0, O0, IO1, O1, IO2, O2, IO3, O3, IO4, O4, IO5, O5>
2388where
2389    Idx: std::cmp::Ord,
2390    IR0: Iterator<Item = (Idx, R0)>,
2391    IR1: Iterator<Item = (Idx, R1)>,
2392    IO0: Iterator<Item = (Idx, O0)>,
2393    IO1: Iterator<Item = (Idx, O1)>,
2394    IO2: Iterator<Item = (Idx, O2)>,
2395    IO3: Iterator<Item = (Idx, O3)>,
2396    IO4: Iterator<Item = (Idx, O4)>,
2397    IO5: Iterator<Item = (Idx, O5)>,
2398    O0: Clone,
2399    O1: Clone,
2400    O2: Clone,
2401    O3: Clone,
2402    O4: Clone,
2403    O5: Clone,
2404{
2405    type Item = (
2406        Idx,
2407        R0,
2408        R1,
2409        Option<O0>,
2410        Option<O1>,
2411        Option<O2>,
2412        Option<O3>,
2413        Option<O4>,
2414        Option<O5>,
2415    );
2416
2417    #[inline]
2418    fn next(&mut self) -> Option<Self::Item> {
2419        let Self {
2420            r0,
2421            r1,
2422            o0,
2423            o1,
2424            o2,
2425            o3,
2426            o4,
2427            o5,
2428            o0_data_latest,
2429            o1_data_latest,
2430            o2_data_latest,
2431            o3_data_latest,
2432            o4_data_latest,
2433            o5_data_latest,
2434        } = self;
2435
2436        let (r0_index, r0_data) = r0.next()?;
2437        let (r1_index, r1_data) = r1.next()?;
2438
2439        let max_index = [r0_index, r1_index].into_iter().max()?;
2440
2441        let mut o0_data = None;
2442        while let Some((_, data)) = o0.next_if(|(index, _)| index <= &max_index) {
2443            o0_data = Some(data);
2444        }
2445        let o0_data = o0_data.or(o0_data_latest.take());
2446        o0_data_latest.clone_from(&o0_data);
2447
2448        let mut o1_data = None;
2449        while let Some((_, data)) = o1.next_if(|(index, _)| index <= &max_index) {
2450            o1_data = Some(data);
2451        }
2452        let o1_data = o1_data.or(o1_data_latest.take());
2453        o1_data_latest.clone_from(&o1_data);
2454
2455        let mut o2_data = None;
2456        while let Some((_, data)) = o2.next_if(|(index, _)| index <= &max_index) {
2457            o2_data = Some(data);
2458        }
2459        let o2_data = o2_data.or(o2_data_latest.take());
2460        o2_data_latest.clone_from(&o2_data);
2461
2462        let mut o3_data = None;
2463        while let Some((_, data)) = o3.next_if(|(index, _)| index <= &max_index) {
2464            o3_data = Some(data);
2465        }
2466        let o3_data = o3_data.or(o3_data_latest.take());
2467        o3_data_latest.clone_from(&o3_data);
2468
2469        let mut o4_data = None;
2470        while let Some((_, data)) = o4.next_if(|(index, _)| index <= &max_index) {
2471            o4_data = Some(data);
2472        }
2473        let o4_data = o4_data.or(o4_data_latest.take());
2474        o4_data_latest.clone_from(&o4_data);
2475
2476        let mut o5_data = None;
2477        while let Some((_, data)) = o5.next_if(|(index, _)| index <= &max_index) {
2478            o5_data = Some(data);
2479        }
2480        let o5_data = o5_data.or(o5_data_latest.take());
2481        o5_data_latest.clone_from(&o5_data);
2482
2483        Some((
2484            max_index, r0_data, r1_data, o0_data, o1_data, o2_data, o3_data, o4_data, o5_data,
2485        ))
2486    }
2487}
2488
2489/// Returns a new [`RangeZip2x7`] iterator.
2490///
2491/// The number of elements in a range zip iterator corresponds to the number of elements in the
2492/// shortest of its required iterators (`r0`, `r1`).
2493///
2494/// Each call to `next` is guaranteed to yield the next value for each required iterator,
2495/// as well as the most recent index amongst all of them.
2496///
2497/// Optional iterators accumulate their state and yield their most recent value (if any),
2498/// each time the required iterators fire.
2499pub fn range_zip_2x7<
2500    Idx,
2501    IR0,
2502    R0,
2503    IR1,
2504    R1,
2505    IO0,
2506    O0,
2507    IO1,
2508    O1,
2509    IO2,
2510    O2,
2511    IO3,
2512    O3,
2513    IO4,
2514    O4,
2515    IO5,
2516    O5,
2517    IO6,
2518    O6,
2519>(
2520    r0: IR0,
2521    r1: IR1,
2522    o0: IO0,
2523    o1: IO1,
2524    o2: IO2,
2525    o3: IO3,
2526    o4: IO4,
2527    o5: IO5,
2528    o6: IO6,
2529) -> RangeZip2x7<
2530    Idx,
2531    IR0::IntoIter,
2532    R0,
2533    IR1::IntoIter,
2534    R1,
2535    IO0::IntoIter,
2536    O0,
2537    IO1::IntoIter,
2538    O1,
2539    IO2::IntoIter,
2540    O2,
2541    IO3::IntoIter,
2542    O3,
2543    IO4::IntoIter,
2544    O4,
2545    IO5::IntoIter,
2546    O5,
2547    IO6::IntoIter,
2548    O6,
2549>
2550where
2551    Idx: std::cmp::Ord,
2552    IR0: IntoIterator<Item = (Idx, R0)>,
2553    IR1: IntoIterator<Item = (Idx, R1)>,
2554    IO0: IntoIterator<Item = (Idx, O0)>,
2555    IO1: IntoIterator<Item = (Idx, O1)>,
2556    IO2: IntoIterator<Item = (Idx, O2)>,
2557    IO3: IntoIterator<Item = (Idx, O3)>,
2558    IO4: IntoIterator<Item = (Idx, O4)>,
2559    IO5: IntoIterator<Item = (Idx, O5)>,
2560    IO6: IntoIterator<Item = (Idx, O6)>,
2561{
2562    RangeZip2x7 {
2563        r0: r0.into_iter(),
2564        r1: r1.into_iter(),
2565        o0: o0.into_iter().peekable(),
2566        o1: o1.into_iter().peekable(),
2567        o2: o2.into_iter().peekable(),
2568        o3: o3.into_iter().peekable(),
2569        o4: o4.into_iter().peekable(),
2570        o5: o5.into_iter().peekable(),
2571        o6: o6.into_iter().peekable(),
2572
2573        o0_data_latest: None,
2574        o1_data_latest: None,
2575        o2_data_latest: None,
2576        o3_data_latest: None,
2577        o4_data_latest: None,
2578        o5_data_latest: None,
2579        o6_data_latest: None,
2580    }
2581}
2582
2583/// Implements a range zip iterator combinator with 2 required iterators and 2 optional
2584/// iterators.
2585///
2586/// See [`range_zip_2x7`] for more information.
2587pub struct RangeZip2x7<
2588    Idx,
2589    IR0,
2590    R0,
2591    IR1,
2592    R1,
2593    IO0,
2594    O0,
2595    IO1,
2596    O1,
2597    IO2,
2598    O2,
2599    IO3,
2600    O3,
2601    IO4,
2602    O4,
2603    IO5,
2604    O5,
2605    IO6,
2606    O6,
2607> where
2608    Idx: std::cmp::Ord,
2609    IR0: Iterator<Item = (Idx, R0)>,
2610    IR1: Iterator<Item = (Idx, R1)>,
2611    IO0: Iterator<Item = (Idx, O0)>,
2612    IO1: Iterator<Item = (Idx, O1)>,
2613    IO2: Iterator<Item = (Idx, O2)>,
2614    IO3: Iterator<Item = (Idx, O3)>,
2615    IO4: Iterator<Item = (Idx, O4)>,
2616    IO5: Iterator<Item = (Idx, O5)>,
2617    IO6: Iterator<Item = (Idx, O6)>,
2618{
2619    r0: IR0,
2620    r1: IR1,
2621    o0: Peekable<IO0>,
2622    o1: Peekable<IO1>,
2623    o2: Peekable<IO2>,
2624    o3: Peekable<IO3>,
2625    o4: Peekable<IO4>,
2626    o5: Peekable<IO5>,
2627    o6: Peekable<IO6>,
2628
2629    o0_data_latest: Option<O0>,
2630    o1_data_latest: Option<O1>,
2631    o2_data_latest: Option<O2>,
2632    o3_data_latest: Option<O3>,
2633    o4_data_latest: Option<O4>,
2634    o5_data_latest: Option<O5>,
2635    o6_data_latest: Option<O6>,
2636}
2637
2638impl<Idx, IR0, R0, IR1, R1, IO0, O0, IO1, O1, IO2, O2, IO3, O3, IO4, O4, IO5, O5, IO6, O6> Iterator
2639    for RangeZip2x7<
2640        Idx,
2641        IR0,
2642        R0,
2643        IR1,
2644        R1,
2645        IO0,
2646        O0,
2647        IO1,
2648        O1,
2649        IO2,
2650        O2,
2651        IO3,
2652        O3,
2653        IO4,
2654        O4,
2655        IO5,
2656        O5,
2657        IO6,
2658        O6,
2659    >
2660where
2661    Idx: std::cmp::Ord,
2662    IR0: Iterator<Item = (Idx, R0)>,
2663    IR1: Iterator<Item = (Idx, R1)>,
2664    IO0: Iterator<Item = (Idx, O0)>,
2665    IO1: Iterator<Item = (Idx, O1)>,
2666    IO2: Iterator<Item = (Idx, O2)>,
2667    IO3: Iterator<Item = (Idx, O3)>,
2668    IO4: Iterator<Item = (Idx, O4)>,
2669    IO5: Iterator<Item = (Idx, O5)>,
2670    IO6: Iterator<Item = (Idx, O6)>,
2671    O0: Clone,
2672    O1: Clone,
2673    O2: Clone,
2674    O3: Clone,
2675    O4: Clone,
2676    O5: Clone,
2677    O6: Clone,
2678{
2679    type Item = (
2680        Idx,
2681        R0,
2682        R1,
2683        Option<O0>,
2684        Option<O1>,
2685        Option<O2>,
2686        Option<O3>,
2687        Option<O4>,
2688        Option<O5>,
2689        Option<O6>,
2690    );
2691
2692    #[inline]
2693    fn next(&mut self) -> Option<Self::Item> {
2694        let Self {
2695            r0,
2696            r1,
2697            o0,
2698            o1,
2699            o2,
2700            o3,
2701            o4,
2702            o5,
2703            o6,
2704            o0_data_latest,
2705            o1_data_latest,
2706            o2_data_latest,
2707            o3_data_latest,
2708            o4_data_latest,
2709            o5_data_latest,
2710            o6_data_latest,
2711        } = self;
2712
2713        let (r0_index, r0_data) = r0.next()?;
2714        let (r1_index, r1_data) = r1.next()?;
2715
2716        let max_index = [r0_index, r1_index].into_iter().max()?;
2717
2718        let mut o0_data = None;
2719        while let Some((_, data)) = o0.next_if(|(index, _)| index <= &max_index) {
2720            o0_data = Some(data);
2721        }
2722        let o0_data = o0_data.or(o0_data_latest.take());
2723        o0_data_latest.clone_from(&o0_data);
2724
2725        let mut o1_data = None;
2726        while let Some((_, data)) = o1.next_if(|(index, _)| index <= &max_index) {
2727            o1_data = Some(data);
2728        }
2729        let o1_data = o1_data.or(o1_data_latest.take());
2730        o1_data_latest.clone_from(&o1_data);
2731
2732        let mut o2_data = None;
2733        while let Some((_, data)) = o2.next_if(|(index, _)| index <= &max_index) {
2734            o2_data = Some(data);
2735        }
2736        let o2_data = o2_data.or(o2_data_latest.take());
2737        o2_data_latest.clone_from(&o2_data);
2738
2739        let mut o3_data = None;
2740        while let Some((_, data)) = o3.next_if(|(index, _)| index <= &max_index) {
2741            o3_data = Some(data);
2742        }
2743        let o3_data = o3_data.or(o3_data_latest.take());
2744        o3_data_latest.clone_from(&o3_data);
2745
2746        let mut o4_data = None;
2747        while let Some((_, data)) = o4.next_if(|(index, _)| index <= &max_index) {
2748            o4_data = Some(data);
2749        }
2750        let o4_data = o4_data.or(o4_data_latest.take());
2751        o4_data_latest.clone_from(&o4_data);
2752
2753        let mut o5_data = None;
2754        while let Some((_, data)) = o5.next_if(|(index, _)| index <= &max_index) {
2755            o5_data = Some(data);
2756        }
2757        let o5_data = o5_data.or(o5_data_latest.take());
2758        o5_data_latest.clone_from(&o5_data);
2759
2760        let mut o6_data = None;
2761        while let Some((_, data)) = o6.next_if(|(index, _)| index <= &max_index) {
2762            o6_data = Some(data);
2763        }
2764        let o6_data = o6_data.or(o6_data_latest.take());
2765        o6_data_latest.clone_from(&o6_data);
2766
2767        Some((
2768            max_index, r0_data, r1_data, o0_data, o1_data, o2_data, o3_data, o4_data, o5_data,
2769            o6_data,
2770        ))
2771    }
2772}
2773
2774/// Returns a new [`RangeZip2x8`] iterator.
2775///
2776/// The number of elements in a range zip iterator corresponds to the number of elements in the
2777/// shortest of its required iterators (`r0`, `r1`).
2778///
2779/// Each call to `next` is guaranteed to yield the next value for each required iterator,
2780/// as well as the most recent index amongst all of them.
2781///
2782/// Optional iterators accumulate their state and yield their most recent value (if any),
2783/// each time the required iterators fire.
2784pub fn range_zip_2x8<
2785    Idx,
2786    IR0,
2787    R0,
2788    IR1,
2789    R1,
2790    IO0,
2791    O0,
2792    IO1,
2793    O1,
2794    IO2,
2795    O2,
2796    IO3,
2797    O3,
2798    IO4,
2799    O4,
2800    IO5,
2801    O5,
2802    IO6,
2803    O6,
2804    IO7,
2805    O7,
2806>(
2807    r0: IR0,
2808    r1: IR1,
2809    o0: IO0,
2810    o1: IO1,
2811    o2: IO2,
2812    o3: IO3,
2813    o4: IO4,
2814    o5: IO5,
2815    o6: IO6,
2816    o7: IO7,
2817) -> RangeZip2x8<
2818    Idx,
2819    IR0::IntoIter,
2820    R0,
2821    IR1::IntoIter,
2822    R1,
2823    IO0::IntoIter,
2824    O0,
2825    IO1::IntoIter,
2826    O1,
2827    IO2::IntoIter,
2828    O2,
2829    IO3::IntoIter,
2830    O3,
2831    IO4::IntoIter,
2832    O4,
2833    IO5::IntoIter,
2834    O5,
2835    IO6::IntoIter,
2836    O6,
2837    IO7::IntoIter,
2838    O7,
2839>
2840where
2841    Idx: std::cmp::Ord,
2842    IR0: IntoIterator<Item = (Idx, R0)>,
2843    IR1: IntoIterator<Item = (Idx, R1)>,
2844    IO0: IntoIterator<Item = (Idx, O0)>,
2845    IO1: IntoIterator<Item = (Idx, O1)>,
2846    IO2: IntoIterator<Item = (Idx, O2)>,
2847    IO3: IntoIterator<Item = (Idx, O3)>,
2848    IO4: IntoIterator<Item = (Idx, O4)>,
2849    IO5: IntoIterator<Item = (Idx, O5)>,
2850    IO6: IntoIterator<Item = (Idx, O6)>,
2851    IO7: IntoIterator<Item = (Idx, O7)>,
2852{
2853    RangeZip2x8 {
2854        r0: r0.into_iter(),
2855        r1: r1.into_iter(),
2856        o0: o0.into_iter().peekable(),
2857        o1: o1.into_iter().peekable(),
2858        o2: o2.into_iter().peekable(),
2859        o3: o3.into_iter().peekable(),
2860        o4: o4.into_iter().peekable(),
2861        o5: o5.into_iter().peekable(),
2862        o6: o6.into_iter().peekable(),
2863        o7: o7.into_iter().peekable(),
2864
2865        o0_data_latest: None,
2866        o1_data_latest: None,
2867        o2_data_latest: None,
2868        o3_data_latest: None,
2869        o4_data_latest: None,
2870        o5_data_latest: None,
2871        o6_data_latest: None,
2872        o7_data_latest: None,
2873    }
2874}
2875
2876/// Implements a range zip iterator combinator with 2 required iterators and 2 optional
2877/// iterators.
2878///
2879/// See [`range_zip_2x8`] for more information.
2880pub struct RangeZip2x8<
2881    Idx,
2882    IR0,
2883    R0,
2884    IR1,
2885    R1,
2886    IO0,
2887    O0,
2888    IO1,
2889    O1,
2890    IO2,
2891    O2,
2892    IO3,
2893    O3,
2894    IO4,
2895    O4,
2896    IO5,
2897    O5,
2898    IO6,
2899    O6,
2900    IO7,
2901    O7,
2902> where
2903    Idx: std::cmp::Ord,
2904    IR0: Iterator<Item = (Idx, R0)>,
2905    IR1: Iterator<Item = (Idx, R1)>,
2906    IO0: Iterator<Item = (Idx, O0)>,
2907    IO1: Iterator<Item = (Idx, O1)>,
2908    IO2: Iterator<Item = (Idx, O2)>,
2909    IO3: Iterator<Item = (Idx, O3)>,
2910    IO4: Iterator<Item = (Idx, O4)>,
2911    IO5: Iterator<Item = (Idx, O5)>,
2912    IO6: Iterator<Item = (Idx, O6)>,
2913    IO7: Iterator<Item = (Idx, O7)>,
2914{
2915    r0: IR0,
2916    r1: IR1,
2917    o0: Peekable<IO0>,
2918    o1: Peekable<IO1>,
2919    o2: Peekable<IO2>,
2920    o3: Peekable<IO3>,
2921    o4: Peekable<IO4>,
2922    o5: Peekable<IO5>,
2923    o6: Peekable<IO6>,
2924    o7: Peekable<IO7>,
2925
2926    o0_data_latest: Option<O0>,
2927    o1_data_latest: Option<O1>,
2928    o2_data_latest: Option<O2>,
2929    o3_data_latest: Option<O3>,
2930    o4_data_latest: Option<O4>,
2931    o5_data_latest: Option<O5>,
2932    o6_data_latest: Option<O6>,
2933    o7_data_latest: Option<O7>,
2934}
2935
2936impl<Idx, IR0, R0, IR1, R1, IO0, O0, IO1, O1, IO2, O2, IO3, O3, IO4, O4, IO5, O5, IO6, O6, IO7, O7>
2937    Iterator
2938    for RangeZip2x8<
2939        Idx,
2940        IR0,
2941        R0,
2942        IR1,
2943        R1,
2944        IO0,
2945        O0,
2946        IO1,
2947        O1,
2948        IO2,
2949        O2,
2950        IO3,
2951        O3,
2952        IO4,
2953        O4,
2954        IO5,
2955        O5,
2956        IO6,
2957        O6,
2958        IO7,
2959        O7,
2960    >
2961where
2962    Idx: std::cmp::Ord,
2963    IR0: Iterator<Item = (Idx, R0)>,
2964    IR1: Iterator<Item = (Idx, R1)>,
2965    IO0: Iterator<Item = (Idx, O0)>,
2966    IO1: Iterator<Item = (Idx, O1)>,
2967    IO2: Iterator<Item = (Idx, O2)>,
2968    IO3: Iterator<Item = (Idx, O3)>,
2969    IO4: Iterator<Item = (Idx, O4)>,
2970    IO5: Iterator<Item = (Idx, O5)>,
2971    IO6: Iterator<Item = (Idx, O6)>,
2972    IO7: Iterator<Item = (Idx, O7)>,
2973    O0: Clone,
2974    O1: Clone,
2975    O2: Clone,
2976    O3: Clone,
2977    O4: Clone,
2978    O5: Clone,
2979    O6: Clone,
2980    O7: Clone,
2981{
2982    type Item = (
2983        Idx,
2984        R0,
2985        R1,
2986        Option<O0>,
2987        Option<O1>,
2988        Option<O2>,
2989        Option<O3>,
2990        Option<O4>,
2991        Option<O5>,
2992        Option<O6>,
2993        Option<O7>,
2994    );
2995
2996    #[inline]
2997    fn next(&mut self) -> Option<Self::Item> {
2998        let Self {
2999            r0,
3000            r1,
3001            o0,
3002            o1,
3003            o2,
3004            o3,
3005            o4,
3006            o5,
3007            o6,
3008            o7,
3009            o0_data_latest,
3010            o1_data_latest,
3011            o2_data_latest,
3012            o3_data_latest,
3013            o4_data_latest,
3014            o5_data_latest,
3015            o6_data_latest,
3016            o7_data_latest,
3017        } = self;
3018
3019        let (r0_index, r0_data) = r0.next()?;
3020        let (r1_index, r1_data) = r1.next()?;
3021
3022        let max_index = [r0_index, r1_index].into_iter().max()?;
3023
3024        let mut o0_data = None;
3025        while let Some((_, data)) = o0.next_if(|(index, _)| index <= &max_index) {
3026            o0_data = Some(data);
3027        }
3028        let o0_data = o0_data.or(o0_data_latest.take());
3029        o0_data_latest.clone_from(&o0_data);
3030
3031        let mut o1_data = None;
3032        while let Some((_, data)) = o1.next_if(|(index, _)| index <= &max_index) {
3033            o1_data = Some(data);
3034        }
3035        let o1_data = o1_data.or(o1_data_latest.take());
3036        o1_data_latest.clone_from(&o1_data);
3037
3038        let mut o2_data = None;
3039        while let Some((_, data)) = o2.next_if(|(index, _)| index <= &max_index) {
3040            o2_data = Some(data);
3041        }
3042        let o2_data = o2_data.or(o2_data_latest.take());
3043        o2_data_latest.clone_from(&o2_data);
3044
3045        let mut o3_data = None;
3046        while let Some((_, data)) = o3.next_if(|(index, _)| index <= &max_index) {
3047            o3_data = Some(data);
3048        }
3049        let o3_data = o3_data.or(o3_data_latest.take());
3050        o3_data_latest.clone_from(&o3_data);
3051
3052        let mut o4_data = None;
3053        while let Some((_, data)) = o4.next_if(|(index, _)| index <= &max_index) {
3054            o4_data = Some(data);
3055        }
3056        let o4_data = o4_data.or(o4_data_latest.take());
3057        o4_data_latest.clone_from(&o4_data);
3058
3059        let mut o5_data = None;
3060        while let Some((_, data)) = o5.next_if(|(index, _)| index <= &max_index) {
3061            o5_data = Some(data);
3062        }
3063        let o5_data = o5_data.or(o5_data_latest.take());
3064        o5_data_latest.clone_from(&o5_data);
3065
3066        let mut o6_data = None;
3067        while let Some((_, data)) = o6.next_if(|(index, _)| index <= &max_index) {
3068            o6_data = Some(data);
3069        }
3070        let o6_data = o6_data.or(o6_data_latest.take());
3071        o6_data_latest.clone_from(&o6_data);
3072
3073        let mut o7_data = None;
3074        while let Some((_, data)) = o7.next_if(|(index, _)| index <= &max_index) {
3075            o7_data = Some(data);
3076        }
3077        let o7_data = o7_data.or(o7_data_latest.take());
3078        o7_data_latest.clone_from(&o7_data);
3079
3080        Some((
3081            max_index, r0_data, r1_data, o0_data, o1_data, o2_data, o3_data, o4_data, o5_data,
3082            o6_data, o7_data,
3083        ))
3084    }
3085}
3086
3087/// Returns a new [`RangeZip2x9`] iterator.
3088///
3089/// The number of elements in a range zip iterator corresponds to the number of elements in the
3090/// shortest of its required iterators (`r0`, `r1`).
3091///
3092/// Each call to `next` is guaranteed to yield the next value for each required iterator,
3093/// as well as the most recent index amongst all of them.
3094///
3095/// Optional iterators accumulate their state and yield their most recent value (if any),
3096/// each time the required iterators fire.
3097pub fn range_zip_2x9<
3098    Idx,
3099    IR0,
3100    R0,
3101    IR1,
3102    R1,
3103    IO0,
3104    O0,
3105    IO1,
3106    O1,
3107    IO2,
3108    O2,
3109    IO3,
3110    O3,
3111    IO4,
3112    O4,
3113    IO5,
3114    O5,
3115    IO6,
3116    O6,
3117    IO7,
3118    O7,
3119    IO8,
3120    O8,
3121>(
3122    r0: IR0,
3123    r1: IR1,
3124    o0: IO0,
3125    o1: IO1,
3126    o2: IO2,
3127    o3: IO3,
3128    o4: IO4,
3129    o5: IO5,
3130    o6: IO6,
3131    o7: IO7,
3132    o8: IO8,
3133) -> RangeZip2x9<
3134    Idx,
3135    IR0::IntoIter,
3136    R0,
3137    IR1::IntoIter,
3138    R1,
3139    IO0::IntoIter,
3140    O0,
3141    IO1::IntoIter,
3142    O1,
3143    IO2::IntoIter,
3144    O2,
3145    IO3::IntoIter,
3146    O3,
3147    IO4::IntoIter,
3148    O4,
3149    IO5::IntoIter,
3150    O5,
3151    IO6::IntoIter,
3152    O6,
3153    IO7::IntoIter,
3154    O7,
3155    IO8::IntoIter,
3156    O8,
3157>
3158where
3159    Idx: std::cmp::Ord,
3160    IR0: IntoIterator<Item = (Idx, R0)>,
3161    IR1: IntoIterator<Item = (Idx, R1)>,
3162    IO0: IntoIterator<Item = (Idx, O0)>,
3163    IO1: IntoIterator<Item = (Idx, O1)>,
3164    IO2: IntoIterator<Item = (Idx, O2)>,
3165    IO3: IntoIterator<Item = (Idx, O3)>,
3166    IO4: IntoIterator<Item = (Idx, O4)>,
3167    IO5: IntoIterator<Item = (Idx, O5)>,
3168    IO6: IntoIterator<Item = (Idx, O6)>,
3169    IO7: IntoIterator<Item = (Idx, O7)>,
3170    IO8: IntoIterator<Item = (Idx, O8)>,
3171{
3172    RangeZip2x9 {
3173        r0: r0.into_iter(),
3174        r1: r1.into_iter(),
3175        o0: o0.into_iter().peekable(),
3176        o1: o1.into_iter().peekable(),
3177        o2: o2.into_iter().peekable(),
3178        o3: o3.into_iter().peekable(),
3179        o4: o4.into_iter().peekable(),
3180        o5: o5.into_iter().peekable(),
3181        o6: o6.into_iter().peekable(),
3182        o7: o7.into_iter().peekable(),
3183        o8: o8.into_iter().peekable(),
3184
3185        o0_data_latest: None,
3186        o1_data_latest: None,
3187        o2_data_latest: None,
3188        o3_data_latest: None,
3189        o4_data_latest: None,
3190        o5_data_latest: None,
3191        o6_data_latest: None,
3192        o7_data_latest: None,
3193        o8_data_latest: None,
3194    }
3195}
3196
3197/// Implements a range zip iterator combinator with 2 required iterators and 2 optional
3198/// iterators.
3199///
3200/// See [`range_zip_2x9`] for more information.
3201pub struct RangeZip2x9<
3202    Idx,
3203    IR0,
3204    R0,
3205    IR1,
3206    R1,
3207    IO0,
3208    O0,
3209    IO1,
3210    O1,
3211    IO2,
3212    O2,
3213    IO3,
3214    O3,
3215    IO4,
3216    O4,
3217    IO5,
3218    O5,
3219    IO6,
3220    O6,
3221    IO7,
3222    O7,
3223    IO8,
3224    O8,
3225> where
3226    Idx: std::cmp::Ord,
3227    IR0: Iterator<Item = (Idx, R0)>,
3228    IR1: Iterator<Item = (Idx, R1)>,
3229    IO0: Iterator<Item = (Idx, O0)>,
3230    IO1: Iterator<Item = (Idx, O1)>,
3231    IO2: Iterator<Item = (Idx, O2)>,
3232    IO3: Iterator<Item = (Idx, O3)>,
3233    IO4: Iterator<Item = (Idx, O4)>,
3234    IO5: Iterator<Item = (Idx, O5)>,
3235    IO6: Iterator<Item = (Idx, O6)>,
3236    IO7: Iterator<Item = (Idx, O7)>,
3237    IO8: Iterator<Item = (Idx, O8)>,
3238{
3239    r0: IR0,
3240    r1: IR1,
3241    o0: Peekable<IO0>,
3242    o1: Peekable<IO1>,
3243    o2: Peekable<IO2>,
3244    o3: Peekable<IO3>,
3245    o4: Peekable<IO4>,
3246    o5: Peekable<IO5>,
3247    o6: Peekable<IO6>,
3248    o7: Peekable<IO7>,
3249    o8: Peekable<IO8>,
3250
3251    o0_data_latest: Option<O0>,
3252    o1_data_latest: Option<O1>,
3253    o2_data_latest: Option<O2>,
3254    o3_data_latest: Option<O3>,
3255    o4_data_latest: Option<O4>,
3256    o5_data_latest: Option<O5>,
3257    o6_data_latest: Option<O6>,
3258    o7_data_latest: Option<O7>,
3259    o8_data_latest: Option<O8>,
3260}
3261
3262impl<
3263    Idx,
3264    IR0,
3265    R0,
3266    IR1,
3267    R1,
3268    IO0,
3269    O0,
3270    IO1,
3271    O1,
3272    IO2,
3273    O2,
3274    IO3,
3275    O3,
3276    IO4,
3277    O4,
3278    IO5,
3279    O5,
3280    IO6,
3281    O6,
3282    IO7,
3283    O7,
3284    IO8,
3285    O8,
3286> Iterator
3287    for RangeZip2x9<
3288        Idx,
3289        IR0,
3290        R0,
3291        IR1,
3292        R1,
3293        IO0,
3294        O0,
3295        IO1,
3296        O1,
3297        IO2,
3298        O2,
3299        IO3,
3300        O3,
3301        IO4,
3302        O4,
3303        IO5,
3304        O5,
3305        IO6,
3306        O6,
3307        IO7,
3308        O7,
3309        IO8,
3310        O8,
3311    >
3312where
3313    Idx: std::cmp::Ord,
3314    IR0: Iterator<Item = (Idx, R0)>,
3315    IR1: Iterator<Item = (Idx, R1)>,
3316    IO0: Iterator<Item = (Idx, O0)>,
3317    IO1: Iterator<Item = (Idx, O1)>,
3318    IO2: Iterator<Item = (Idx, O2)>,
3319    IO3: Iterator<Item = (Idx, O3)>,
3320    IO4: Iterator<Item = (Idx, O4)>,
3321    IO5: Iterator<Item = (Idx, O5)>,
3322    IO6: Iterator<Item = (Idx, O6)>,
3323    IO7: Iterator<Item = (Idx, O7)>,
3324    IO8: Iterator<Item = (Idx, O8)>,
3325    O0: Clone,
3326    O1: Clone,
3327    O2: Clone,
3328    O3: Clone,
3329    O4: Clone,
3330    O5: Clone,
3331    O6: Clone,
3332    O7: Clone,
3333    O8: Clone,
3334{
3335    type Item = (
3336        Idx,
3337        R0,
3338        R1,
3339        Option<O0>,
3340        Option<O1>,
3341        Option<O2>,
3342        Option<O3>,
3343        Option<O4>,
3344        Option<O5>,
3345        Option<O6>,
3346        Option<O7>,
3347        Option<O8>,
3348    );
3349
3350    #[inline]
3351    fn next(&mut self) -> Option<Self::Item> {
3352        let Self {
3353            r0,
3354            r1,
3355            o0,
3356            o1,
3357            o2,
3358            o3,
3359            o4,
3360            o5,
3361            o6,
3362            o7,
3363            o8,
3364            o0_data_latest,
3365            o1_data_latest,
3366            o2_data_latest,
3367            o3_data_latest,
3368            o4_data_latest,
3369            o5_data_latest,
3370            o6_data_latest,
3371            o7_data_latest,
3372            o8_data_latest,
3373        } = self;
3374
3375        let (r0_index, r0_data) = r0.next()?;
3376        let (r1_index, r1_data) = r1.next()?;
3377
3378        let max_index = [r0_index, r1_index].into_iter().max()?;
3379
3380        let mut o0_data = None;
3381        while let Some((_, data)) = o0.next_if(|(index, _)| index <= &max_index) {
3382            o0_data = Some(data);
3383        }
3384        let o0_data = o0_data.or(o0_data_latest.take());
3385        o0_data_latest.clone_from(&o0_data);
3386
3387        let mut o1_data = None;
3388        while let Some((_, data)) = o1.next_if(|(index, _)| index <= &max_index) {
3389            o1_data = Some(data);
3390        }
3391        let o1_data = o1_data.or(o1_data_latest.take());
3392        o1_data_latest.clone_from(&o1_data);
3393
3394        let mut o2_data = None;
3395        while let Some((_, data)) = o2.next_if(|(index, _)| index <= &max_index) {
3396            o2_data = Some(data);
3397        }
3398        let o2_data = o2_data.or(o2_data_latest.take());
3399        o2_data_latest.clone_from(&o2_data);
3400
3401        let mut o3_data = None;
3402        while let Some((_, data)) = o3.next_if(|(index, _)| index <= &max_index) {
3403            o3_data = Some(data);
3404        }
3405        let o3_data = o3_data.or(o3_data_latest.take());
3406        o3_data_latest.clone_from(&o3_data);
3407
3408        let mut o4_data = None;
3409        while let Some((_, data)) = o4.next_if(|(index, _)| index <= &max_index) {
3410            o4_data = Some(data);
3411        }
3412        let o4_data = o4_data.or(o4_data_latest.take());
3413        o4_data_latest.clone_from(&o4_data);
3414
3415        let mut o5_data = None;
3416        while let Some((_, data)) = o5.next_if(|(index, _)| index <= &max_index) {
3417            o5_data = Some(data);
3418        }
3419        let o5_data = o5_data.or(o5_data_latest.take());
3420        o5_data_latest.clone_from(&o5_data);
3421
3422        let mut o6_data = None;
3423        while let Some((_, data)) = o6.next_if(|(index, _)| index <= &max_index) {
3424            o6_data = Some(data);
3425        }
3426        let o6_data = o6_data.or(o6_data_latest.take());
3427        o6_data_latest.clone_from(&o6_data);
3428
3429        let mut o7_data = None;
3430        while let Some((_, data)) = o7.next_if(|(index, _)| index <= &max_index) {
3431            o7_data = Some(data);
3432        }
3433        let o7_data = o7_data.or(o7_data_latest.take());
3434        o7_data_latest.clone_from(&o7_data);
3435
3436        let mut o8_data = None;
3437        while let Some((_, data)) = o8.next_if(|(index, _)| index <= &max_index) {
3438            o8_data = Some(data);
3439        }
3440        let o8_data = o8_data.or(o8_data_latest.take());
3441        o8_data_latest.clone_from(&o8_data);
3442
3443        Some((
3444            max_index, r0_data, r1_data, o0_data, o1_data, o2_data, o3_data, o4_data, o5_data,
3445            o6_data, o7_data, o8_data,
3446        ))
3447    }
3448}