1use crate::Backing;
2use crate::ClosedRange;
3use crate::Endpoint;
4use crate::NormalizedRangeIter;
5use crate::RangeCase;
6use crate::RangeVec;
7
8#[repr(transparent)]
10struct ComplementGenerator<T: Endpoint> {
11 next_start: T,
12}
13
14impl<T: Endpoint> ComplementGenerator<T> {
15 #[inline(always)]
16 fn new() -> Self {
17 Self {
18 next_start: T::min_value(),
19 }
20 }
21
22 #[inline(always)]
23 fn next(self, range: (T, T)) -> (Option<Self>, Option<(T, T)>) {
24 let next_start = self.next_start;
25 let (start, stop) = range;
26 let gap = start
33 .decrease_toward(next_start)
34 .map(|prev| (next_start, prev));
35
36 let next_self = stop.next_after().map(|next_start| Self { next_start });
37
38 (next_self, gap)
39 }
40
41 #[inline(always)]
42 fn end(self) -> (T, T) {
43 (self.next_start, T::max_value())
44 }
45}
46
47pub struct ComplementIterator<Ranges>
48where
49 Ranges: Sized + NormalizedRangeIter + Iterator<Item: ClosedRange>,
51{
52 state: Option<(
53 ComplementGenerator<<<Ranges as Iterator>::Item as ClosedRange>::EndT>,
54 Ranges,
55 )>,
56}
57
58impl<Ranges> ComplementIterator<Ranges>
59where
60 Ranges: Sized + NormalizedRangeIter + Iterator<Item: ClosedRange>,
61{
62 #[inline(always)]
63 pub fn new(ranges: Ranges) -> Self {
64 Self {
65 state: Some((ComplementGenerator::new(), ranges)),
66 }
67 }
68}
69
70type Pair<T> = (T, T);
71
72impl<Ranges> Iterator for ComplementIterator<Ranges>
73where
74 Ranges: Sized + NormalizedRangeIter + Iterator<Item: ClosedRange>,
75{
76 type Item = Pair<<<Ranges as Iterator>::Item as ClosedRange>::EndT>;
77
78 fn next(&mut self) -> Option<Self::Item> {
79 loop {
80 let (self_cg, ranges) = self.state.as_mut()?;
81 let mut cg = ComplementGenerator::new();
82 core::mem::swap(&mut cg, self_cg);
83
84 let Some(range) = ranges.next() else {
85 self.state = None;
86 return Some(cg.end());
87 };
88
89 let (cg, ret) = cg.next(range.get());
90 match cg {
91 None => {
92 self.state = None;
93 return ret;
94 }
95 Some(cg) => {
96 *self_cg = cg;
97 }
98 }
99
100 if ret.is_some() {
101 return ret;
102 }
103 }
104 }
105
106 #[inline]
107 fn size_hint(&self) -> (usize, Option<usize>) {
108 let (min, max) = match self.state.as_ref() {
109 Some((_, ranges)) => ranges.size_hint(),
110 None => (0, None),
111 };
112
113 (min.saturating_sub(1), max.map(|max| max.saturating_add(2)))
118 }
119}
120
121impl<Ranges> crate::private::Sealed for ComplementIterator<Ranges> where
122 Ranges: Sized + NormalizedRangeIter + Iterator<Item: ClosedRange>
123{
124}
125
126impl<Ranges> NormalizedRangeIter for ComplementIterator<Ranges> where
127 Ranges: Sized + NormalizedRangeIter + Iterator<Item: ClosedRange>
128{
129}
130
131impl<Ranges> core::iter::FusedIterator for ComplementIterator<Ranges> where
134 Ranges: Sized + NormalizedRangeIter + Iterator<Item: ClosedRange>
135{
136}
137
138#[inline(never)]
139fn complement_impl<T: Endpoint>(normalized_intervals: Backing<T>) -> RangeVec<T> {
140 use core::cmp::Ordering;
142
143 let mut intervals = normalized_intervals;
144 let mut prefix_len = 0;
145
146 'out: {
147 let mut cg = ComplementGenerator::new();
148
149 for i in 0..intervals.len() {
150 assert!(prefix_len <= i);
151 let (start, stop) = intervals[i];
152
153 debug_assert!(start.cmp_end(stop) <= Ordering::Equal);
155
156 let (next_cg, gap) = cg.next(intervals[i]);
157 if let Some(gap) = gap {
158 intervals[prefix_len] = gap;
159 prefix_len += 1;
160 }
161
162 match next_cg {
163 Some(next_cg) => cg = next_cg,
164 None => {
165 intervals.truncate(prefix_len);
166 break 'out;
167 }
168 }
169 }
170
171 let final_interval = cg.end();
172 if prefix_len < intervals.len() {
173 intervals[prefix_len] = final_interval;
174 intervals.truncate(prefix_len + 1);
175 } else {
176 intervals.push(final_interval);
177 }
178 }
179
180 unsafe { RangeVec::new_unchecked(intervals) }
181}
182
183#[inline(always)]
189pub fn complement_vec<T: Endpoint>(intervals: impl Into<RangeCase<T>>) -> RangeVec<T> {
190 crate::normalize_vec(intervals).into_complement()
191}
192
193impl<T: Endpoint> RangeVec<T> {
194 #[inline(always)]
199 pub fn complement(&self) -> RangeVec<T> {
200 self.iter().complement().collect_range_vec()
201 }
202
203 #[inline(always)]
207 pub fn into_complement(self) -> RangeVec<T> {
208 #[cfg(feature = "internal_checks")]
209 let expected = self.complement();
210
211 let ret = complement_impl(self.into_inner());
212 #[cfg(feature = "internal_checks")]
213 assert!(&expected.eqv(&ret));
214
215 ret
216 }
217}
218
219#[cfg(test)]
220#[cfg_attr(coverage_nightly, coverage(off))]
221mod test {
222 use super::*;
223 use alloc::vec;
224 use alloc::vec::Vec;
225 use smallvec::smallvec;
226
227 #[test]
228 fn test_complement_smoke() {
229 use crate::normalize_vec;
230 use crate::IntoNormalizedRangeIter;
231
232 fn complement(
233 x: impl IntoNormalizedRangeIter<Item = (u8, u8)>,
234 ) -> impl NormalizedRangeIter<Item = (u8, u8)> {
235 x.into_iter().complement()
236 }
237
238 let empty: &[(u8, u8)] = &[];
239 assert_eq!(
240 complement_vec(empty.to_vec()).into_vec(),
241 vec![(0u8, 255u8)]
242 );
243 assert_eq!(
244 normalize_vec(empty.to_vec()).into_complement().into_vec(),
245 vec![(0u8, 255u8)]
246 );
247
248 assert_eq!(
249 normalize_vec(empty.to_vec()).complement().into_vec(),
250 vec![(0u8, 255u8)]
251 );
252
253 {
254 let mut universe = normalize_vec(empty.to_vec()).into_iter().complement();
255
256 assert_eq!(universe.next(), Some((0u8, 255u8)));
257 assert_eq!(universe.next(), None); assert_eq!(universe.next(), None);
259 }
260
261 {
262 let (min, max) = complement(normalize_vec(empty.to_vec())).size_hint();
263
264 assert!(min <= 1);
265 assert!(max.expect("should have max") >= 1);
266 }
267
268 {
269 let (min, max) = complement(normalize_vec(vec![(1u8, 10u8), (11u8, 11u8)])).size_hint();
270
271 assert!(min <= 2);
272 assert!(max.expect("should have max") >= 2);
273 }
274
275 let smallvec: smallvec::SmallVec<[_; crate::INLINE_SIZE]> =
276 smallvec![(1u8, 10u8), (11u8, 11u8)];
277 assert_eq!(
278 complement_vec(smallvec).into_vec(),
279 vec![(0u8, 0u8), (12u8, 255u8)]
280 );
281 assert_eq!(
282 complement(&normalize_vec(vec![(1u8, 10u8), (11u8, 11u8)]))
283 .collect_range_vec()
284 .into_vec(),
285 vec![(0u8, 0u8), (12u8, 255u8)]
286 );
287
288 let largervec: smallvec::SmallVec<[_; crate::INLINE_SIZE + 1]> = smallvec![(1u8, 255u8)];
289 assert_eq!(complement_vec(largervec).into_vec(), vec![(0u8, 0u8)]);
290
291 let smallervec: smallvec::SmallVec<[_; crate::INLINE_SIZE.saturating_sub(1)]> =
292 smallvec![(1u8, 255u8)];
293 assert_eq!(
294 complement(&normalize_vec(smallervec))
295 .collect_range_vec()
296 .into_vec(),
297 vec![(0u8, 0u8)]
298 );
299
300 assert_eq!(
301 complement_vec(vec![(1u8, 254u8)]).into_vec(),
302 vec![(0u8, 0u8), (255u8, 255u8)]
303 );
304 assert_eq!(
305 complement(&normalize_vec(vec![(1u8, 254u8)]))
306 .collect_range_vec()
307 .into_vec(),
308 vec![(0u8, 0u8), (255u8, 255u8)]
309 );
310 assert_eq!(
311 complement(normalize_vec(vec![(1u8, 254u8)]))
312 .collect_range_vec()
313 .into_vec(),
314 vec![(0u8, 0u8), (255u8, 255u8)]
315 );
316
317 assert_eq!(complement_vec(vec![(0u8, 255u8)]).into_vec(), vec![]);
318 assert_eq!(
319 complement(normalize_vec(vec![(0u8, 255u8)]))
320 .collect_range_vec()
321 .into_vec(),
322 vec![]
323 );
324
325 assert_eq!(
326 complement_vec(vec![(0u8, 254u8)]).into_vec(),
327 vec![(255u8, 255u8)]
328 );
329 assert_eq!(
330 complement(normalize_vec(vec![(0u8, 254u8)])).collect::<Vec<_>>(),
331 vec![(255u8, 255u8)]
332 );
333
334 assert_eq!(
335 complement(&normalize_vec(vec![(0u8, 254u8)]))
336 .collect_range_vec()
337 .into_vec(),
338 vec![(255u8, 255u8)]
339 );
340 }
341
342 proptest::proptest! {
343 #[test]
344 fn test_increase(ranges: Vec<(u8, u8)>) {
345 use crate::ranges_to_bits;
346
347 let marks = ranges_to_bits(&ranges).into_iter().map(|x| !x).collect::<Vec<bool>>();
348
349 assert_eq!(&ranges_to_bits(&complement_vec(ranges.clone())), &marks);
350
351 let ranges = RangeVec::from_vec(ranges);
352 assert_eq!(&ranges_to_bits(&complement_vec(ranges.clone())), &marks);
353
354 assert_eq!(&ranges_to_bits(&ranges.clone().complement()), &marks);
355 assert_eq!(&ranges_to_bits(&ranges.clone().into_complement()), &marks);
356
357 assert_eq!(&ranges_to_bits(&ranges.iter().complement().collect_range_vec()), &marks);
358 }
359
360 #[test]
361 fn test_self_inverse_f32(ranges: Vec<(f32, f32)>) {
362 let ranges = RangeVec::from_vec(ranges);
363 let complement = ranges.complement();
364 let double_complement = complement.into_complement();
365
366 assert_eq!(ranges, double_complement);
367 }
368
369 #[test]
370 fn test_self_inverse_f64(ranges: Vec<(f64, f64)>) {
371 let ranges = RangeVec::from_vec(ranges);
372 let complement = ranges.complement();
373 let double_complement = complement.into_complement();
374
375 assert_eq!(ranges, double_complement);
376 }
377 }
378}