1use core::iter::FusedIterator;
2use core::ops::RangeInclusive;
3
4use itertools::{Itertools, KMergeBy, MergeBy};
5
6use crate::Integer;
7use crate::map::ValueRef;
8use crate::range_values::SetPriorityMap;
9
10use crate::sorted_disjoint_map::{Priority, PrioritySortedStartsMap, SortedDisjointMap};
11
12#[derive(Clone, Debug)]
14#[must_use = "iterators are lazy and do nothing unless consumed"]
15pub struct MergeMap<
16 T,
17 VR,
18 L: Iterator<Item = (RangeInclusive<T>, VR)>,
19 R: Iterator<Item = (RangeInclusive<T>, VR)>,
20> {
21 #[allow(clippy::type_complexity)]
22 iter: MergeBy<
23 SetPriorityMap<T, VR, L>,
24 SetPriorityMap<T, VR, R>,
25 fn(&Priority<T, VR>, &Priority<T, VR>) -> bool,
26 >,
27}
28
29impl<T, VR, L, R> MergeMap<T, VR, L, R>
30where
31 T: Integer,
32 VR: ValueRef,
33 L: SortedDisjointMap<T, VR>,
34 R: SortedDisjointMap<T, VR>,
35{
36 pub(crate) fn new(left: L, right: R) -> Self {
37 let left = SetPriorityMap::new(left, 0);
38 let right = SetPriorityMap::new(right, 1);
39 Self {
40 iter: left.merge_by(right, |a, b| a.start() < b.start()),
42 }
43 }
44}
45
46impl<T, VR, L, R> FusedIterator for MergeMap<T, VR, L, R>
47where
48 T: Integer,
49 VR: ValueRef,
50 L: SortedDisjointMap<T, VR>,
51 R: SortedDisjointMap<T, VR>,
52{
53}
54
55impl<T, VR, L, R> Iterator for MergeMap<T, VR, L, R>
56where
57 T: Integer,
58 VR: ValueRef,
59 L: SortedDisjointMap<T, VR>,
60 R: SortedDisjointMap<T, VR>,
61{
62 type Item = Priority<T, VR>;
63
64 fn next(&mut self) -> Option<Self::Item> {
65 self.iter.next()
66 }
67
68 fn size_hint(&self) -> (usize, Option<usize>) {
69 self.iter.size_hint()
70 }
71}
72
73impl<T, VR, L, R> PrioritySortedStartsMap<T, VR> for MergeMap<T, VR, L, R>
74where
75 T: Integer,
76 VR: ValueRef,
77 L: SortedDisjointMap<T, VR>,
78 R: SortedDisjointMap<T, VR>,
79{
80}
81
82#[derive(Clone, Debug)]
84#[allow(clippy::module_name_repetitions)]
85#[must_use = "iterators are lazy and do nothing unless consumed"]
86pub struct KMergeMap<T, VR, I>
87where
88 I: Iterator<Item = (RangeInclusive<T>, VR)>,
89{
90 #[allow(clippy::type_complexity)]
91 iter: KMergeBy<SetPriorityMap<T, VR, I>, fn(&Priority<T, VR>, &Priority<T, VR>) -> bool>,
92}
93
94type KMergeSetPriorityMap<T, VR, I> =
95 KMergeBy<SetPriorityMap<T, VR, I>, fn(&Priority<T, VR>, &Priority<T, VR>) -> bool>;
96
97impl<T, VR, I> KMergeMap<T, VR, I>
98where
99 T: Integer,
100 VR: ValueRef,
101 I: SortedDisjointMap<T, VR>,
102{
103 pub(crate) fn new<K>(iter: K) -> Self
107 where
108 K: IntoIterator<Item = I>,
109 {
110 let iter = iter.into_iter().enumerate().map(|(i, x)| {
112 let priority_number = i;
113 SetPriorityMap::new(x, priority_number)
114 });
115 let iter: KMergeSetPriorityMap<T, VR, I> = iter.kmerge_by(|a, b| {
117 a.start() < b.start()
119 });
120 Self { iter }
121 }
122}
123
124impl<T, VR, I> FusedIterator for KMergeMap<T, VR, I>
125where
126 T: Integer,
127 VR: ValueRef,
128 I: SortedDisjointMap<T, VR>,
129{
130}
131
132impl<T, VR, I> Iterator for KMergeMap<T, VR, I>
133where
134 T: Integer,
135 VR: ValueRef,
136 I: SortedDisjointMap<T, VR>,
137{
138 type Item = Priority<T, VR>;
139
140 fn next(&mut self) -> Option<Self::Item> {
141 self.iter.next()
142 }
143
144 fn size_hint(&self) -> (usize, Option<usize>) {
145 self.iter.size_hint()
146 }
147}
148
149impl<T, VR, I> PrioritySortedStartsMap<T, VR> for KMergeMap<T, VR, I>
150where
151 T: Integer,
152 VR: ValueRef,
153 I: SortedDisjointMap<T, VR>,
154{
155}