1use crate::Backing;
2use crate::ClosedRange;
3use crate::ClosedRangeEnd;
4use crate::ClosedRangeVal;
5use crate::Endpoint;
6use crate::NormalizedRangeIter;
7use crate::RangeCase;
8use crate::RangeVec;
9
10#[repr(transparent)]
12struct ComplementGenerator<T: Endpoint> {
13 next_start: T,
14}
15
16impl<T: Endpoint> ComplementGenerator<T> {
17 #[inline(always)]
18 fn new() -> Self {
19 Self {
20 next_start: T::min_value(),
21 }
22 }
23
24 #[inline(always)]
25 fn next(self, range: (T, T)) -> (Option<Self>, Option<(T, T)>) {
26 let next_start = self.next_start;
27 let (start, stop) = range;
28 let gap = start
35 .decrease_toward(next_start)
36 .map(|prev| (next_start, prev));
37
38 let next_self = stop.next_after().map(|next_start| Self { next_start });
39
40 (next_self, gap)
41 }
42
43 #[inline(always)]
44 fn end(self) -> (T, T) {
45 (self.next_start, T::max_value())
46 }
47}
48
49pub struct ComplementIterator<Ranges>
50where
51 Ranges: Sized + NormalizedRangeIter + Iterator<Item: ClosedRange>,
53{
54 state: Option<(
55 ComplementGenerator<ClosedRangeEnd<<Ranges as Iterator>::Item>>,
56 Ranges,
57 )>,
58}
59
60impl<Ranges> ComplementIterator<Ranges>
61where
62 Ranges: Sized + NormalizedRangeIter + Iterator<Item: ClosedRange>,
63{
64 #[inline(always)]
65 pub fn new(ranges: Ranges) -> Self {
66 Self {
67 state: Some((ComplementGenerator::new(), ranges)),
68 }
69 }
70}
71
72impl<Ranges> Iterator for ComplementIterator<Ranges>
73where
74 Ranges: Sized + NormalizedRangeIter + Iterator<Item: ClosedRange>,
75{
76 type Item = ClosedRangeVal<<Ranges as Iterator>::Item>;
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)]
189#[must_use]
190pub fn complement_vec<T: Endpoint>(intervals: impl Into<RangeCase<T>>) -> RangeVec<T> {
191 crate::normalize_vec(intervals).into_complement()
192}
193
194impl<T: Endpoint> RangeVec<T> {
195 #[inline(always)]
200 #[must_use]
201 pub fn complement(&self) -> RangeVec<T> {
202 self.iter().complement().collect_range_vec()
203 }
204
205 #[inline(always)]
209 #[must_use]
210 pub fn into_complement(self) -> RangeVec<T> {
211 #[cfg(feature = "internal_checks")]
212 let expected = self.complement();
213
214 let ret = complement_impl(self.into_inner());
215 #[cfg(feature = "internal_checks")]
216 assert!(&expected.eqv(&ret));
217
218 ret
219 }
220}
221
222#[cfg(test)]
223#[cfg_attr(coverage_nightly, coverage(off))]
224mod test {
225 use super::*;
226 use alloc::vec;
227 use alloc::vec::Vec;
228 use smallvec::smallvec;
229
230 #[test]
231 fn test_complement_smoke() {
232 use crate::normalize_vec;
233 use crate::IntoNormalizedRangeIter;
234
235 fn complement(
236 x: impl IntoNormalizedRangeIter<Item = (u8, u8)>,
237 ) -> impl NormalizedRangeIter<Item = (u8, u8)> {
238 x.into_iter().complement()
239 }
240
241 let empty: &[(u8, u8)] = &[];
242 assert_eq!(
243 complement_vec(empty.to_vec()).into_vec(),
244 vec![(0u8, 255u8)]
245 );
246 assert_eq!(
247 normalize_vec(empty.to_vec()).into_complement().into_vec(),
248 vec![(0u8, 255u8)]
249 );
250
251 assert_eq!(
252 normalize_vec(empty.to_vec()).complement().into_vec(),
253 vec![(0u8, 255u8)]
254 );
255
256 {
257 let mut universe = normalize_vec(empty.to_vec()).into_iter().complement();
258
259 assert_eq!(universe.next(), Some((0u8, 255u8)));
260 assert_eq!(universe.next(), None); assert_eq!(universe.next(), None);
262 }
263
264 {
265 let (min, max) = complement(normalize_vec(empty.to_vec())).size_hint();
266
267 assert!(min <= 1);
268 assert!(max.expect("should have max") >= 1);
269 }
270
271 {
272 let (min, max) = complement(normalize_vec(vec![(1u8, 10u8), (11u8, 11u8)])).size_hint();
273
274 assert!(min <= 2);
275 assert!(max.expect("should have max") >= 2);
276 }
277
278 let smallvec: smallvec::SmallVec<[_; crate::INLINE_SIZE]> =
279 smallvec![(1u8, 10u8), (11u8, 11u8)];
280 assert_eq!(
281 complement_vec(smallvec).into_vec(),
282 vec![(0u8, 0u8), (12u8, 255u8)]
283 );
284 assert_eq!(
285 complement(&normalize_vec(vec![(1u8, 10u8), (11u8, 11u8)]))
286 .collect_range_vec()
287 .into_vec(),
288 vec![(0u8, 0u8), (12u8, 255u8)]
289 );
290
291 let largervec: smallvec::SmallVec<[_; crate::INLINE_SIZE + 1]> = smallvec![(1u8, 255u8)];
292 assert_eq!(complement_vec(largervec).into_vec(), vec![(0u8, 0u8)]);
293
294 let smallervec: smallvec::SmallVec<[_; crate::INLINE_SIZE.saturating_sub(1)]> =
295 smallvec![(1u8, 255u8)];
296 assert_eq!(
297 complement(&normalize_vec(smallervec))
298 .collect_range_vec()
299 .into_vec(),
300 vec![(0u8, 0u8)]
301 );
302
303 assert_eq!(
304 complement_vec(vec![(1u8, 254u8)]).into_vec(),
305 vec![(0u8, 0u8), (255u8, 255u8)]
306 );
307 assert_eq!(
308 complement(&normalize_vec(vec![(1u8, 254u8)]))
309 .collect_range_vec()
310 .into_vec(),
311 vec![(0u8, 0u8), (255u8, 255u8)]
312 );
313 assert_eq!(
314 complement(normalize_vec(vec![(1u8, 254u8)]))
315 .collect_range_vec()
316 .into_vec(),
317 vec![(0u8, 0u8), (255u8, 255u8)]
318 );
319
320 assert_eq!(complement_vec(vec![(0u8, 255u8)]).into_vec(), vec![]);
321 assert_eq!(
322 complement(normalize_vec(vec![(0u8, 255u8)]))
323 .collect_range_vec()
324 .into_vec(),
325 vec![]
326 );
327
328 assert_eq!(
329 complement_vec(vec![(0u8, 254u8)]).into_vec(),
330 vec![(255u8, 255u8)]
331 );
332 assert_eq!(
333 complement(normalize_vec(vec![(0u8, 254u8)])).collect::<Vec<_>>(),
334 vec![(255u8, 255u8)]
335 );
336
337 assert_eq!(
338 complement(&normalize_vec(vec![(0u8, 254u8)]))
339 .collect_range_vec()
340 .into_vec(),
341 vec![(255u8, 255u8)]
342 );
343 }
344
345 proptest::proptest! {
346 #[test]
347 fn test_increase(ranges: Vec<(u8, u8)>) {
348 use crate::ranges_to_bits;
349
350 let marks = ranges_to_bits(&ranges).into_iter().map(|x| !x).collect::<Vec<bool>>();
351
352 assert_eq!(&ranges_to_bits(&complement_vec(ranges.clone())), &marks);
353
354 let ranges = RangeVec::from_vec(ranges);
355 assert_eq!(&ranges_to_bits(&complement_vec(ranges.clone())), &marks);
356
357 assert_eq!(&ranges_to_bits(&ranges.clone().complement()), &marks);
358 assert_eq!(&ranges_to_bits(&ranges.clone().into_complement()), &marks);
359
360 assert_eq!(&ranges_to_bits(&ranges.iter().complement().collect_range_vec()), &marks);
361 }
362
363 #[test]
364 fn test_self_inverse_f32(ranges: Vec<(f32, f32)>) {
365 let ranges = RangeVec::from_vec(ranges);
366 let complement = ranges.complement();
367 let double_complement = complement.into_complement();
368
369 assert_eq!(ranges, double_complement);
370 }
371
372 #[test]
373 fn test_self_inverse_f64(ranges: Vec<(f64, f64)>) {
374 let ranges = RangeVec::from_vec(ranges);
375 let complement = ranges.complement();
376 let double_complement = complement.into_complement();
377
378 assert_eq!(ranges, double_complement);
379 }
380 }
381}