1use core::{iter::FusedIterator, ops::RangeInclusive};
2
3use itertools::{Itertools, KMergeBy, MergeBy};
4
5use crate::{Integer, SortedDisjoint, SortedStarts};
6
7#[must_use = "iterators are lazy and do nothing unless consumed"]
9#[derive(Clone, Debug)]
10pub struct Merge<T, L, R>
11where
12 T: Integer,
13 L: SortedDisjoint<T>,
14 R: SortedDisjoint<T>,
15{
16 #[allow(clippy::type_complexity)]
17 iter: MergeBy<L, R, fn(&RangeInclusive<T>, &RangeInclusive<T>) -> bool>,
18}
19
20impl<T, L, R> Merge<T, L, R>
21where
22 T: Integer,
23 L: SortedDisjoint<T>,
24 R: SortedDisjoint<T>,
25{
26 #[inline]
30 pub(crate) fn new(left: L, right: R) -> Self {
31 Self {
32 iter: left.merge_by(right, |a, b| a.start() < b.start()),
33 }
34 }
35}
36
37impl<T, L, R> FusedIterator for Merge<T, L, R>
38where
39 T: Integer,
40 L: SortedDisjoint<T>,
41 R: SortedDisjoint<T>,
42{
43}
44
45impl<T, L, R> Iterator for Merge<T, L, R>
46where
47 T: Integer,
48 L: SortedDisjoint<T>,
49 R: SortedDisjoint<T>,
50{
51 type Item = RangeInclusive<T>;
52
53 fn next(&mut self) -> Option<Self::Item> {
54 self.iter.next()
55 }
56
57 fn size_hint(&self) -> (usize, Option<usize>) {
58 self.iter.size_hint()
59 }
60}
61
62impl<T, L, R> SortedStarts<T> for Merge<T, L, R>
63where
64 T: Integer,
65 L: SortedDisjoint<T>,
66 R: SortedDisjoint<T>,
67{
68}
69
70#[derive(Clone, Debug)]
72#[allow(clippy::module_name_repetitions)]
73#[must_use = "iterators are lazy and do nothing unless consumed"]
74pub struct KMerge<T, I>
75where
76 T: Integer,
77 I: SortedDisjoint<T>,
78{
79 #[allow(clippy::type_complexity)]
80 iter: KMergeBy<I, fn(&RangeInclusive<T>, &RangeInclusive<T>) -> bool>,
81}
82
83type RangeMergeIter<T, I> = KMergeBy<I, fn(&RangeInclusive<T>, &RangeInclusive<T>) -> bool>;
84
85impl<T, I> KMerge<T, I>
86where
87 T: Integer,
88 I: SortedDisjoint<T>,
89{
90 pub(crate) fn new<K>(iter: K) -> Self
91 where
92 K: IntoIterator<Item = I>,
93 {
94 let iter = iter.into_iter();
95 let iter: RangeMergeIter<T, I> = iter.kmerge_by(|a, b| a.start() < b.start());
97 Self { iter }
98 }
99}
100
101impl<T, I> FusedIterator for KMerge<T, I>
102where
103 T: Integer,
104 I: SortedDisjoint<T>,
105{
106}
107
108impl<T, I> Iterator for KMerge<T, I>
109where
110 T: Integer,
111 I: SortedDisjoint<T>,
112{
113 type Item = RangeInclusive<T>;
114
115 fn next(&mut self) -> Option<Self::Item> {
116 self.iter.next()
117 }
118
119 fn size_hint(&self) -> (usize, Option<usize>) {
120 self.iter.size_hint()
121 }
122}
123
124impl<T, I> SortedStarts<T> for KMerge<T, I>
125where
126 T: Integer,
127 I: SortedDisjoint<T>,
128{
129}