range_set_blaze/
unsorted_disjoint.rs1use crate::{Integer, 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"]
10#[allow(clippy::redundant_pub_crate)]
11pub(crate) struct UnsortedDisjoint<T, I> {
12 iter: I,
13 option_range: Option<RangeInclusive<T>>,
14 min_value_plus_2: T,
15}
16
17impl<T, I> UnsortedDisjoint<T, I>
18where
19 T: Integer,
20 I: Iterator<Item = RangeInclusive<T>>, {
22 #[inline]
23 pub(crate) fn new(iter: I) -> Self {
24 Self {
25 iter,
26 option_range: None,
27 min_value_plus_2: T::min_value().add_one().add_one(),
28 }
29 }
30}
31
32impl<T, I> FusedIterator for UnsortedDisjoint<T, I>
33where
34 T: Integer,
35 I: Iterator<Item = RangeInclusive<T>> + FusedIterator,
36{
37}
38
39impl<T, I> Iterator for UnsortedDisjoint<T, I>
40where
41 T: Integer,
42 I: Iterator<Item = RangeInclusive<T>>,
43{
44 type Item = RangeInclusive<T>;
45
46 fn next(&mut self) -> Option<Self::Item> {
47 loop {
48 let Some(range) = self.iter.next() else {
49 return self.option_range.take();
50 };
51 let (next_start, next_end) = range.into_inner();
52 if next_start > next_end {
53 continue;
54 }
55 let Some(self_range) = self.option_range.clone() else {
56 self.option_range = Some(next_start..=next_end);
57 continue;
58 };
59
60 let (self_start, self_end) = self_range.into_inner();
61 if (next_start >= self.min_value_plus_2 && self_end <= next_start.sub_one().sub_one())
62 || (self_start >= self.min_value_plus_2
63 && next_end <= self_start.sub_one().sub_one())
64 {
65 let result = Some(self_start..=self_end);
66 self.option_range = Some(next_start..=next_end);
67 return result;
68 }
69 self.option_range = Some(min(self_start, next_start)..=max(self_end, next_end));
70 }
72 }
73
74 fn size_hint(&self) -> (usize, Option<usize>) {
77 let (lower, upper) = self.iter.size_hint();
78 let lower = min(lower, 1);
79 if self.option_range.is_some() {
80 (lower, upper.map(|x| x + 1))
81 } else {
82 (lower, upper)
83 }
84 }
85}
86
87#[must_use = "iterators are lazy and do nothing unless consumed"]
88#[allow(clippy::redundant_pub_crate)]
89pub(crate) struct SortedDisjointWithLenSoFar<T: Integer, I> {
90 iter: I,
91 len: <T as Integer>::SafeLen,
92}
93
94impl<T, I> SortedDisjointWithLenSoFar<T, I>
95where
96 T: Integer,
97 I: Iterator<Item = RangeInclusive<T>> + SortedDisjoint<T>,
98{
99 #[inline]
100 pub(crate) fn new(iter: I) -> Self {
101 Self {
102 iter,
103 len: T::SafeLen::zero(),
104 }
105 }
106}
107
108impl<T: Integer, I> SortedDisjointWithLenSoFar<T, I>
109where
110 I: SortedDisjoint<T>,
111{
112 pub(crate) const fn len_so_far(&self) -> <T as Integer>::SafeLen {
113 self.len
114 }
115}
116
117impl<T: Integer, I> FusedIterator for SortedDisjointWithLenSoFar<T, I> where
118 I: SortedDisjoint<T> + FusedIterator
119{
120}
121
122impl<T: Integer, I> Iterator for SortedDisjointWithLenSoFar<T, I>
123where
124 I: SortedDisjoint<T>,
125{
126 type Item = (T, T);
127
128 fn next(&mut self) -> Option<Self::Item> {
129 if let Some(range) = self.iter.next() {
130 let (start, end) = range.clone().into_inner();
131 debug_assert!(start <= end);
132 self.len += T::safe_len(&range);
133 Some((start, end))
134 } else {
135 None
136 }
137 }
138 fn size_hint(&self) -> (usize, Option<usize>) {
139 self.iter.size_hint()
140 }
141}
142
143#[derive(Clone, Debug)]
144#[must_use = "iterators are lazy and do nothing unless consumed"]
145pub struct AssumeSortedStarts<I> {
147 pub(crate) iter: I,
148}
149
150impl<T, I> FusedIterator for AssumeSortedStarts<I>
151where
152 T: Integer,
153 I: Iterator<Item = RangeInclusive<T>> + FusedIterator,
154{
155}
156
157impl<T: Integer, I> SortedStarts<T> for AssumeSortedStarts<I> where
158 I: Iterator<Item = RangeInclusive<T>> + FusedIterator
159{
160}
161
162impl<T, I> AssumeSortedStarts<I>
163where
164 T: Integer,
165 I: Iterator<Item = RangeInclusive<T>> + FusedIterator,
166{
167 #[inline]
169 pub fn new<J: IntoIterator<IntoIter = I>>(iter: J) -> Self {
170 Self {
171 iter: iter.into_iter(),
172 }
173 }
174}
175
176impl<T, I> Iterator for AssumeSortedStarts<I>
177where
178 T: Integer,
179 I: Iterator<Item = RangeInclusive<T>> + FusedIterator,
180{
181 type Item = RangeInclusive<T>;
182
183 fn next(&mut self) -> Option<Self::Item> {
184 self.iter.next()
185 }
186
187 fn size_hint(&self) -> (usize, Option<usize>) {
188 self.iter.size_hint()
189 }
190}