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