1use crate::map::ValueRef;
2use crate::range_values::ExpectDebugUnwrapRelease;
3use crate::sorted_disjoint_map::{Priority, PrioritySortedStartsMap};
4use crate::{Integer, map::EndValue, sorted_disjoint_map::SortedDisjointMap};
5use core::ops::RangeInclusive;
6use core::{
7 cmp::{max, min},
8 iter::FusedIterator,
9 marker::PhantomData,
10};
11use num_traits::Zero;
12
13#[must_use = "iterators are lazy and do nothing unless consumed"]
14#[allow(clippy::redundant_pub_crate)]
15pub(crate) struct UnsortedPriorityMap<T, VR, I> {
16 iter: I,
17 option_priority: Option<Priority<T, VR>>,
18 min_value_plus_2: T,
19 priority_number: usize,
20}
21
22impl<T, VR, I> UnsortedPriorityMap<T, VR, I>
23where
24 T: Integer,
25 VR: ValueRef,
26 I: Iterator<Item = (RangeInclusive<T>, VR)>, {
28 #[inline]
29 pub(crate) fn new(into_iter: I) -> Self {
30 Self {
31 iter: into_iter,
32 option_priority: None,
33 min_value_plus_2: T::min_value().add_one().add_one(),
34 priority_number: 0,
35 }
36 }
37}
38
39impl<T, VR, I> FusedIterator for UnsortedPriorityMap<T, VR, I>
40where
41 T: Integer,
42 VR: ValueRef,
43 I: Iterator<Item = (RangeInclusive<T>, VR)>,
44{
45}
46
47impl<T, VR, I> Iterator for UnsortedPriorityMap<T, VR, I>
48where
49 T: Integer,
50 VR: ValueRef,
51 I: Iterator<Item = (RangeInclusive<T>, VR)>,
52{
53 type Item = Priority<T, VR>;
54
55 fn next(&mut self) -> Option<Self::Item> {
56 loop {
57 let Some(next_range_value) = self.iter.next() else {
59 return self.option_priority.take();
60 };
61 let next_priority = Priority::new(next_range_value, self.priority_number);
62 self.priority_number = self
63 .priority_number
64 .checked_add(1)
65 .expect_debug_unwrap_release("underflow");
66
67 let (next_start, next_end) = next_priority.start_and_end();
69 if next_start > next_end {
70 continue;
71 }
72
73 let Some(mut current_priority) = self.option_priority.take() else {
75 self.option_priority = Some(next_priority);
76 continue;
77 };
78
79 let (current_start, current_end) = current_priority.start_and_end();
82 if current_priority.value().borrow() != next_priority.value().borrow()
83 || (next_start >= self.min_value_plus_2
84 && current_end <= next_start.sub_one().sub_one())
85 || (current_start >= self.min_value_plus_2
86 && next_end <= current_start.sub_one().sub_one())
87 {
88 self.option_priority = Some(next_priority);
89 return Some(current_priority);
90 }
91
92 current_priority.set_range(min(current_start, next_start)..=max(current_end, next_end));
94 self.option_priority = Some(current_priority);
95
96 }
98 }
99
100 fn size_hint(&self) -> (usize, Option<usize>) {
103 let (lower, upper) = self.iter.size_hint();
104 let lower = min(lower, 1);
105 if self.option_priority.is_some() {
106 (lower, upper.map(|x| x + 1))
107 } else {
108 (lower, upper)
109 }
110 }
111}
112
113#[must_use = "iterators are lazy and do nothing unless consumed"]
114#[allow(clippy::redundant_pub_crate)]
115pub(crate) struct SortedDisjointMapWithLenSoFar<T: Integer, VR, I> {
116 iter: I,
117 len: <T as Integer>::SafeLen,
118 phantom: PhantomData<VR>,
119}
120
121impl<T, VR, I> SortedDisjointMapWithLenSoFar<T, VR, I>
122where
123 T: Integer,
124 VR: ValueRef,
125 I: SortedDisjointMap<T, VR>,
126{
127 pub(crate) const fn len_so_far(&self) -> <T as Integer>::SafeLen {
128 self.len
129 }
130
131 pub(crate) fn new(iter: I) -> Self {
132 Self {
133 iter,
134 len: <T as Integer>::SafeLen::zero(),
135 phantom: PhantomData,
136 }
137 }
138}
139
140impl<T, VR, I> FusedIterator for SortedDisjointMapWithLenSoFar<T, VR, I>
141where
142 T: Integer,
143 VR: ValueRef,
144 I: SortedDisjointMap<T, VR>,
145{
146}
147
148impl<T, VR, I> Iterator for SortedDisjointMapWithLenSoFar<T, VR, I>
149where
150 T: Integer,
151 VR: ValueRef,
152 I: SortedDisjointMap<T, VR>,
153{
154 type Item = (T, EndValue<T, VR::Target>);
155
156 fn next(&mut self) -> Option<Self::Item> {
157 if let Some((range, value)) = self.iter.next() {
158 let (start, end) = range.clone().into_inner();
159 debug_assert!(start <= end);
160 self.len += T::safe_len(&range);
161 let end_value = EndValue {
162 end,
163 value: value.into_value(),
164 };
165 Some((start, end_value))
166 } else {
167 None
168 }
169 }
170 fn size_hint(&self) -> (usize, Option<usize>) {
171 self.iter.size_hint()
172 }
173}
174
175#[derive(Clone, Debug)]
176#[must_use = "iterators are lazy and do nothing unless consumed"]
177pub struct AssumePrioritySortedStartsMap<I> {
182 iter: I,
183}
184
185impl<T, VR, I> PrioritySortedStartsMap<T, VR> for AssumePrioritySortedStartsMap<I>
186where
187 T: Integer,
188 VR: ValueRef,
189 I: Iterator<Item = Priority<T, VR>> + FusedIterator,
190{
191}
192
193impl<T, VR, I> AssumePrioritySortedStartsMap<I>
194where
195 T: Integer,
196 VR: ValueRef,
197 I: Iterator<Item = Priority<T, VR>> + FusedIterator,
198{
199 pub(crate) const fn new(iter: I) -> Self {
200 Self { iter }
201 }
202}
203
204impl<T, VR, I> FusedIterator for AssumePrioritySortedStartsMap<I>
205where
206 T: Integer,
207 VR: ValueRef,
208 I: Iterator<Item = Priority<T, VR>> + FusedIterator,
209{
210}
211
212impl<T, VR, I> Iterator for AssumePrioritySortedStartsMap<I>
213where
214 T: Integer,
215 VR: ValueRef,
216 I: Iterator<Item = Priority<T, VR>> + FusedIterator,
217{
218 type Item = Priority<T, VR>;
219
220 fn next(&mut self) -> Option<Self::Item> {
221 self.iter.next()
222 }
223
224 fn size_hint(&self) -> (usize, Option<usize>) {
225 self.iter.size_hint()
226 }
227}