1use core::iter::FusedIterator;
2
3use itertools::{Itertools, KMergeBy, MergeBy};
4
5use crate::Integer;
6use crate::map::ValueRef;
7use crate::range_values::SetPriorityMap;
8
9use crate::sorted_disjoint_map::{Priority, PrioritySortedStartsMap, SortedDisjointMap};
10
11#[derive(Clone, Debug)]
13#[must_use = "iterators are lazy and do nothing unless consumed"]
14pub struct MergeMap<T, VR, L, R>
15where
16 T: Integer,
17 VR: ValueRef,
18 L: SortedDisjointMap<T, VR>,
19 R: SortedDisjointMap<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 T: Integer,
89 VR: ValueRef,
90 I: SortedDisjointMap<T, VR>,
91{
92 #[allow(clippy::type_complexity)]
93 iter: KMergeBy<SetPriorityMap<T, VR, I>, fn(&Priority<T, VR>, &Priority<T, VR>) -> bool>,
94}
95
96type KMergeSetPriorityMap<T, VR, I> =
97 KMergeBy<SetPriorityMap<T, VR, I>, fn(&Priority<T, VR>, &Priority<T, VR>) -> bool>;
98
99impl<T, VR, I> KMergeMap<T, VR, I>
100where
101 T: Integer,
102 VR: ValueRef,
103 I: SortedDisjointMap<T, VR>,
104{
105 pub(crate) fn new<K>(iter: K) -> Self
109 where
110 K: IntoIterator<Item = I>,
111 {
112 let iter = iter.into_iter().enumerate().map(|(i, x)| {
114 let priority_number = i;
115 SetPriorityMap::new(x, priority_number)
116 });
117 let iter: KMergeSetPriorityMap<T, VR, I> = iter.kmerge_by(|a, b| {
119 a.start() < b.start()
121 });
122 Self { iter }
123 }
124}
125
126impl<T, VR, I> FusedIterator for KMergeMap<T, VR, I>
127where
128 T: Integer,
129 VR: ValueRef,
130 I: SortedDisjointMap<T, VR>,
131{
132}
133
134impl<T, VR, I> Iterator for KMergeMap<T, VR, I>
135where
136 T: Integer,
137 VR: ValueRef,
138 I: SortedDisjointMap<T, VR>,
139{
140 type Item = Priority<T, VR>;
141
142 fn next(&mut self) -> Option<Self::Item> {
143 self.iter.next()
144 }
145
146 fn size_hint(&self) -> (usize, Option<usize>) {
147 self.iter.size_hint()
148 }
149}
150
151impl<T, VR, I> PrioritySortedStartsMap<T, VR> for KMergeMap<T, VR, I>
152where
153 T: Integer,
154 VR: ValueRef,
155 I: SortedDisjointMap<T, VR>,
156{
157}