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