1use crate::{Integer, RangeSetBlaze, SortedDisjoint, SortedStarts};
2use core::{
3 cmp::{max, min},
4 iter::FusedIterator,
5 ops::RangeInclusive,
6};
7use num_traits::Zero;
8
9#[must_use = "iterators are lazy and do nothing unless consumed"]
10pub(crate) struct UnsortedDisjoint<T, I>
11where
12 T: Integer,
13 I: Iterator<Item = RangeInclusive<T>>,
14{
15 iter: I,
16 option_range: Option<RangeInclusive<T>>,
17 min_value_plus_2: T,
18 two: T,
19}
20
21impl<T, I> From<I> for UnsortedDisjoint<T, I::IntoIter>
22where
23 T: Integer,
24 I: IntoIterator<Item = RangeInclusive<T>>, {
26 fn from(into_iter: I) -> Self {
27 UnsortedDisjoint {
28 iter: into_iter.into_iter(),
29 option_range: None,
30 min_value_plus_2: T::min_value() + T::one() + T::one(),
31 two: T::one() + T::one(),
32 }
33 }
34}
35
36impl<T, I> FusedIterator for UnsortedDisjoint<T, I>
37where
38 T: Integer,
39 I: Iterator<Item = RangeInclusive<T>> + FusedIterator,
40{
41}
42
43impl<T, I> Iterator for UnsortedDisjoint<T, I>
44where
45 T: Integer,
46 I: Iterator<Item = RangeInclusive<T>>,
47{
48 type Item = RangeInclusive<T>;
49
50 fn next(&mut self) -> Option<Self::Item> {
51 loop {
52 let range = match self.iter.next() {
53 Some(r) => r,
54 None => return self.option_range.take(),
55 };
56
57 let (next_start, next_end) = range.into_inner();
58 if next_start > next_end {
59 continue;
60 }
61 assert!(
62 next_end <= T::safe_max_value(),
63 "end must be <= T::safe_max_value()"
64 );
65
66 let Some(self_range) = self.option_range.clone() else {
67 self.option_range = Some(next_start..=next_end);
68 continue;
69 };
70
71 let (self_start, self_end) = self_range.into_inner();
72 if (next_start >= self.min_value_plus_2 && self_end <= next_start - self.two)
73 || (self_start >= self.min_value_plus_2 && next_end <= self_start - self.two)
74 {
75 let result = Some(self_start..=self_end);
76 self.option_range = Some(next_start..=next_end);
77 return result;
78 } else {
79 self.option_range = Some(min(self_start, next_start)..=max(self_end, next_end));
80 continue;
81 }
82 }
83 }
84
85 fn size_hint(&self) -> (usize, Option<usize>) {
88 let (lower, upper) = self.iter.size_hint();
89 let lower = if lower == 0 { 0 } else { 1 };
90 if self.option_range.is_some() {
91 (lower, upper.map(|x| x + 1))
92 } else {
93 (lower, upper)
94 }
95 }
96}
97
98#[must_use = "iterators are lazy and do nothing unless consumed"]
99pub(crate) struct SortedDisjointWithLenSoFar<T, I>
100where
101 T: Integer,
102 I: SortedDisjoint<T>,
103{
104 iter: I,
105 len: <T as Integer>::SafeLen,
106}
107
108impl<T: Integer, I> From<I> for SortedDisjointWithLenSoFar<T, I::IntoIter>
109where
110 I: IntoIterator<Item = RangeInclusive<T>>,
111 I::IntoIter: SortedDisjoint<T>,
112{
113 fn from(into_iter: I) -> Self {
114 SortedDisjointWithLenSoFar {
115 iter: into_iter.into_iter(),
116 len: <T as Integer>::SafeLen::zero(),
117 }
118 }
119}
120
121impl<T: Integer, I> SortedDisjointWithLenSoFar<T, I>
122where
123 I: SortedDisjoint<T>,
124{
125 pub fn len_so_far(&self) -> <T as Integer>::SafeLen {
126 self.len
127 }
128}
129
130impl<T: Integer, I> FusedIterator for SortedDisjointWithLenSoFar<T, I> where
131 I: SortedDisjoint<T> + FusedIterator
132{
133}
134
135impl<T: Integer, I> Iterator for SortedDisjointWithLenSoFar<T, I>
136where
137 I: SortedDisjoint<T>,
138{
139 type Item = (T, T);
140
141 fn next(&mut self) -> Option<Self::Item> {
142 if let Some(range) = self.iter.next() {
143 let (start, end) = range.clone().into_inner();
144 debug_assert!(start <= end && end <= T::safe_max_value());
145 self.len += T::safe_len(&range);
146 Some((start, end))
147 } else {
148 None
149 }
150 }
151 fn size_hint(&self) -> (usize, Option<usize>) {
152 self.iter.size_hint()
153 }
154}
155
156#[derive(Clone, Debug)]
157#[must_use = "iterators are lazy and do nothing unless consumed"]
158
159pub struct AssumeSortedStarts<T, I>
161where
162 T: Integer,
163 I: Iterator<Item = RangeInclusive<T>>,
164{
165 pub(crate) iter: I,
166}
167
168impl<T: Integer, I> SortedStarts<T> for AssumeSortedStarts<T, I> where
169 I: Iterator<Item = RangeInclusive<T>>
170{
171}
172
173impl<T, I> AssumeSortedStarts<T, I>
174where
175 T: Integer,
176 I: Iterator<Item = RangeInclusive<T>>,
177{
178 pub fn new<J: IntoIterator<IntoIter = I>>(iter: J) -> Self {
180 AssumeSortedStarts {
181 iter: iter.into_iter(),
182 }
183 }
184
185 pub fn into_range_set_blaze(self) -> RangeSetBlaze<T>
199 where
200 Self: Sized,
201 {
202 RangeSetBlaze::from_sorted_starts(self)
203 }
204}
205
206impl<T, I> FusedIterator for AssumeSortedStarts<T, I>
207where
208 T: Integer,
209 I: Iterator<Item = RangeInclusive<T>> + FusedIterator,
210{
211}
212
213impl<T, I> Iterator for AssumeSortedStarts<T, I>
214where
215 T: Integer,
216 I: Iterator<Item = RangeInclusive<T>>,
217{
218 type Item = RangeInclusive<T>;
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}