Skip to main content

irange/
lib.rs

1//! A data structure to store and manipulate ranges of integers with set operations.
2//!
3//! [`RangeSet`] holds an arbitrary set of integers as a sorted collection of
4//! non-overlapping inclusive ranges. It is compact for values that come in runs: a
5//! set such as "every codepoint that is a word character" costs a handful of bounds
6//! rather than one entry per value. It supports the usual set algebra:
7//! [`union`], [`intersection`], [`difference`], [`complement`], and the containment
8//! queries [`contains`] and [`contains_all`].
9//!
10//! Supported types: `u8`, `u16`, `u32`, `u64`, `u128`, `usize`, `i8`, `i16`, `i32`,
11//! `i64`, `i128` and `isize`.
12//!
13//! # Example
14//!
15//! ```
16//! use irange::range::AnyRange;
17//! use irange::RangeSet;
18//!
19//! let range1 = RangeSet::<i64>::new_from_ranges(&[AnyRange::from(3..=4), AnyRange::from(7..9)]);
20//! let range2 = RangeSet::<i64>::new_from_range(-2..=4);
21//!
22//! assert_eq!("[ -2..=4 7..=8 ]", range1.union(&range2).to_string());
23//! assert_eq!("[ 3..=4 ]", range1.intersection(&range2).to_string());
24//! assert_eq!("[ 7..=8 ]", range1.difference(&range2).to_string());
25//!
26//! let values: Vec<i64> = range1.union(&range2).iter().collect();
27//! assert_eq!(vec![-2, -1, 0, 1, 2, 3, 4, 7, 8], values);
28//! ```
29//!
30//! # Representation
31//!
32//! A `RangeSet` is a flat `Vec` of inclusive bounds: the elements at an even index are
33//! lower bounds and the elements at an odd index are the matching upper bounds, so
34//! `[ 3..=4 7..=8 ]` is stored as `vec![3, 4, 7, 8]`.
35//!
36//! Every set has exactly one such representation. The bounds are even in number, no
37//! range is inverted, and consecutive ranges are sorted and separated by at least one
38//! value, so two ranges that touch, like `1..=2` and `3..=4`, are merged into `1..=4`.
39//! The constructors maintain this invariant, and [`RangeSet::new_from_bounds`] checks
40//! it when you build a set from raw bounds. Writing to the public field directly
41//! bypasses the check and gives unspecified (but never panicking) results.
42//!
43//! # Complexity
44//!
45//! `n` is the total number of ranges involved. Every operation makes a single ordered
46//! pass over the bounds, so nothing here is worse than linear.
47//!
48//! | Operation | Time | Space |
49//! |---|---|---|
50//! | [`union`], [`intersection`], [`difference`], [`complement`] | `O(n)` | `O(n)` |
51//! | [`has_intersection`], [`contains_all`] | `O(n)` | `O(1)` |
52//! | [`contains`] | `O(log n)` | `O(1)` |
53//! | [`is_total`], [`is_empty`] | `O(1)` | `O(1)` |
54//!
55//! # Operators
56//!
57//! The four operations that build a new set also have an operator, taking references like
58//! those of [`BTreeSet`](std::collections::BTreeSet): `|` for [`union`], `&` for
59//! [`intersection`], `-` for [`difference`] and `!` for [`complement`].
60//!
61//! ```
62//! use irange::RangeSet;
63//!
64//! let a = RangeSet::new_from_range(3..=8);
65//! let b = RangeSet::new_from_range(7..=12);
66//!
67//! assert_eq!(a.union(&b), &a | &b);
68//! assert_eq!(a.intersection(&b), &a & &b);
69//! assert_eq!(a.difference(&b), &a - &b);
70//! assert_eq!(a.complement(), !&a);
71//! ```
72//!
73//! # Iteration
74//!
75//! [`RangeSet::iter`] walks the individual values in order, and `&RangeSet` implements
76//! [`IntoIterator`], so a `for` loop over a set works directly. The iterator is
77//! double-ended, so [`rev`](Iterator::rev) walks the values from the largest down.
78//!
79//! ```
80//! use irange::RangeSet;
81//!
82//! let range = RangeSet::new_from_range(2..=5);
83//!
84//! let ascending: Vec<i32> = (&range).into_iter().collect();
85//! assert_eq!(vec![2, 3, 4, 5], ascending);
86//!
87//! let descending: Vec<i32> = range.iter().rev().collect();
88//! assert_eq!(vec![5, 4, 3, 2], descending);
89//! ```
90//!
91//! # Feature flags
92//!
93//! - `serde`: implement `Serialize` and `Deserialize` for [`RangeSet`], using the flat
94//!   list of bounds as the serialized form. Deserializing validates the invariant above
95//!   and fails with a descriptive error rather than accepting a malformed set.
96//!
97//! [`union`]: RangeSet::union
98//! [`intersection`]: RangeSet::intersection
99//! [`difference`]: RangeSet::difference
100//! [`complement`]: RangeSet::complement
101//! [`contains`]: RangeSet::contains
102//! [`contains_all`]: RangeSet::contains_all
103//! [`has_intersection`]: RangeSet::has_intersection
104//! [`is_total`]: RangeSet::is_total
105//! [`is_empty`]: RangeSet::is_empty
106
107#![warn(missing_docs)]
108#![forbid(unsafe_code)]
109#![cfg_attr(docsrs, feature(doc_cfg))]
110
111/// The README, compiled and run as a doctest so its examples cannot go stale.
112#[cfg(doctest)]
113#[doc = include_str!("../README.md")]
114mod readme {}
115
116#[cfg(feature = "serde")]
117use serde::{Deserialize, Serialize};
118
119use std::ops::{Bound, RangeBounds};
120
121use integer::NumericInteger;
122use range::AnyRange;
123
124/// The integer types a [`RangeSet`] can hold.
125pub mod integer;
126/// A single range of integers, used to build a [`RangeSet`].
127pub mod range;
128
129fn range_to_bounds<T: NumericInteger, R: RangeBounds<T>>(range: &R) -> Option<(T, T)> {
130    let min = match range.start_bound() {
131        Bound::Included(t) => *t,
132        Bound::Excluded(t) => {
133            if *t == T::max_value() {
134                return None;
135            }
136            *t + T::one()
137        }
138        Bound::Unbounded => T::min_value(),
139    };
140    let max = match range.end_bound() {
141        Bound::Included(t) => *t,
142        Bound::Excluded(t) => {
143            if *t == T::min_value() {
144                return None;
145            }
146            *t - T::one()
147        }
148        Bound::Unbounded => T::max_value(),
149    };
150
151    if min > max {
152        None
153    } else {
154        Some((min, max))
155    }
156}
157
158/// A structure holding a collection of `u8`, `u16`, `u32`, `u64`, `u128`, `usize`, `i8`, `i16`, `i32`, `i64`, `i128` or `isize`.
159#[derive(PartialEq, Eq, Hash, Clone, Debug, PartialOrd, Ord)]
160#[cfg_attr(feature = "serde", derive(Serialize))]
161pub struct RangeSet<T: NumericInteger>(
162    /// In this collection all the elements with even index represent the lower bounds (inclusive) and all the odd index represent the upper bounds (inclusive).
163    pub Vec<T>,
164);
165
166#[cfg(feature = "serde")]
167#[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
168impl<'de, T: NumericInteger + Deserialize<'de>> Deserialize<'de> for RangeSet<T> {
169    fn deserialize<D>(deserializer: D) -> Result<RangeSet<T>, D::Error>
170    where
171        D: serde::Deserializer<'de>,
172    {
173        let bounds = Vec::<T>::deserialize(deserializer)?;
174        RangeSet::new_from_bounds(bounds).ok_or_else(|| {
175            serde::de::Error::custom(
176                "invalid RangeSet: expected an even number of inclusive bounds describing sorted, non-overlapping and non-adjacent ranges",
177            )
178        })
179    }
180}
181
182impl<T: NumericInteger> std::fmt::Display for RangeSet<T> {
183    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
184        write!(f, "[ ")?;
185        for bounds in self.0.chunks_exact(2) {
186            write!(f, "{}..={} ", bounds[0], bounds[1])?;
187        }
188        write!(f, "]")
189    }
190}
191
192/// A structure to hold the iterator of a `RangeSet` instance.
193///
194/// It walks the values in order, and backwards from the end with
195/// [`rev`](Iterator::rev) or [`next_back`](DoubleEndedIterator::next_back).
196#[derive(Clone, Debug)]
197pub struct RangeSetIter<'a, T: NumericInteger> {
198    bounds: &'a [T],
199    /// Index of the lower bound of the next range to load from the front.
200    front: usize,
201    /// Index one past the upper bound of the next range to load from the back.
202    /// The ranges that neither end has loaded yet are `bounds[front..back]`.
203    back: usize,
204    /// Values left to yield of the range the front end is walking, as inclusive bounds.
205    current: Option<(T, T)>,
206    /// Values left to yield of the range the back end is walking, as inclusive bounds.
207    current_back: Option<(T, T)>,
208}
209
210impl<T: NumericInteger> Iterator for RangeSetIter<'_, T> {
211    type Item = T;
212
213    fn next(&mut self) -> Option<Self::Item> {
214        // Walk the range the front end already loaded.
215        if let Some((min, max)) = self.current {
216            self.current = if min < max {
217                Some((min + T::one(), max))
218            } else {
219                None
220            };
221            return Some(min);
222        }
223
224        // Load the next range that neither end has claimed. An inverted range, only
225        // reachable from a hand-written `RangeSet`, yields its lower bound alone.
226        if self.front < self.back {
227            let (min, max) = (self.bounds[self.front], self.bounds[self.front + 1]);
228            self.front += 2;
229            if min < max {
230                self.current = Some((min + T::one(), max));
231            }
232            return Some(min);
233        }
234
235        // The ends have met: finish off what the back end started.
236        let (min, max) = self.current_back?;
237        self.current_back = if min < max {
238            Some((min + T::one(), max))
239        } else {
240            None
241        };
242        Some(min)
243    }
244}
245
246impl<T: NumericInteger> DoubleEndedIterator for RangeSetIter<'_, T> {
247    fn next_back(&mut self) -> Option<Self::Item> {
248        // Walk the range the back end already loaded.
249        if let Some((min, max)) = self.current_back {
250            self.current_back = if min < max {
251                Some((min, max - T::one()))
252            } else {
253                None
254            };
255            return Some(max);
256        }
257
258        // Load the last range that neither end has claimed.
259        if self.front < self.back {
260            let (min, max) = (self.bounds[self.back - 2], self.bounds[self.back - 1]);
261            self.back -= 2;
262            // An inverted range yields its lower bound alone, from either end.
263            if min > max {
264                return Some(min);
265            }
266            if min < max {
267                self.current_back = Some((min, max - T::one()));
268            }
269            return Some(max);
270        }
271
272        // The ends have met: finish off what the front end started.
273        let (min, max) = self.current?;
274        self.current = if min < max {
275            Some((min, max - T::one()))
276        } else {
277            None
278        };
279        Some(max)
280    }
281}
282
283impl<T: NumericInteger> std::iter::FusedIterator for RangeSetIter<'_, T> {}
284
285impl<T: NumericInteger> RangeSet<T> {
286    /// Return an iterator to iterate in order over all the values contained.
287    ///
288    /// # Example:
289    ///
290    /// ```
291    /// use irange::RangeSet;
292    ///
293    /// let range = RangeSet::new_from_range(2..=5);
294    ///
295    /// for value in range.iter() {
296    ///     print!("{value} "); // 2 3 4 5
297    /// }
298    /// ```
299    pub fn iter(&self) -> RangeSetIter<'_, T> {
300        // An odd trailing bound, only reachable from a hand-written `RangeSet`, has no
301        // matching upper bound and is ignored.
302        let len = self.0.len();
303        RangeSetIter {
304            bounds: &self.0,
305            front: 0,
306            back: len - len % 2,
307            current: None,
308            current_back: None,
309        }
310    }
311
312    /// Create a new instance from the given range.
313    ///
314    /// # Example:
315    ///
316    /// ```
317    /// use irange::RangeSet;
318    ///
319    /// // Contains 2, 3
320    /// RangeSet::new_from_range(2..4);
321    ///
322    /// // Contains 0, 1
323    /// RangeSet::<u8>::new_from_range(..2);
324    ///
325    /// // Contains 0, 1, 2
326    /// RangeSet::<u32>::new_from_range(..=2);
327    /// ```
328    pub fn new_from_range<R: RangeBounds<T>>(range: R) -> RangeSet<T> {
329        match range_to_bounds(&range) {
330            Some((min, max)) => RangeSet(vec![min, max]),
331            None => RangeSet::empty(),
332        }
333    }
334
335    /// Create a new instance from the given ranges.
336    ///
337    /// # Example:
338    ///
339    /// ```
340    /// use irange::RangeSet;
341    /// use irange::range::AnyRange;
342    ///
343    /// // Contains 3, 4, 7, 8
344    /// RangeSet::<i64>::new_from_ranges(&[AnyRange::from(3..=4), AnyRange::from(7..9)]);
345    /// ```
346    pub fn new_from_ranges(ranges: &[AnyRange<T>]) -> RangeSet<T> {
347        let mut ranges: Vec<(T, T)> = ranges
348            .iter()
349            .map(|range| range.get_bounds())
350            .filter(|(min, max)| max >= min)
351            .copied()
352            .collect();
353        // Ranges that already arrive in order, a common way to build a set, need no sort.
354        let mut is_sorted = true;
355        if let Some((first_min, _)) = ranges.first() {
356            let mut previous_min = *first_min;
357            for (min, _) in &ranges[1..] {
358                if *min < previous_min {
359                    is_sorted = false;
360                    break;
361                }
362                previous_min = *min;
363            }
364        }
365        if !is_sorted {
366            ranges.sort_by_key(|range| range.0);
367        }
368
369        let mut bounds = Vec::with_capacity(ranges.len() * 2);
370        let mut current_max = T::min_value();
371        for (min, max) in ranges {
372            if bounds.is_empty() || (current_max < T::max_value() && min > current_max + T::one()) {
373                bounds.extend_from_slice(&[min, max]);
374                current_max = max;
375            } else if max > current_max {
376                *bounds.last_mut().unwrap() = max;
377                current_max = max;
378            }
379        }
380
381        bounds.shrink_to_fit();
382        RangeSet(bounds)
383    }
384
385    /// Create a new instance from the raw collection of bounds used internally: the elements with
386    /// an even index are the lower bounds (inclusive) and the elements with an odd index are the
387    /// upper bounds (inclusive).
388    ///
389    /// Return `None` if the collection is not a valid representation, i.e. if it does not hold an
390    /// even number of bounds, if a range is inverted, or if two consecutive ranges are not sorted,
391    /// overlap, or merely touch each other (they should be merged into a single range).
392    ///
393    /// # Example:
394    ///
395    /// ```
396    /// use irange::RangeSet;
397    ///
398    /// // Contains 2, 3, 4, 7, 8
399    /// assert!(RangeSet::<u8>::new_from_bounds(vec![2, 4, 7, 8]).is_some());
400    ///
401    /// // 4..=6 and 7..=8 are adjacent, they must be given as a single 4..=8 range
402    /// assert!(RangeSet::<u8>::new_from_bounds(vec![4, 6, 7, 8]).is_none());
403    /// ```
404    pub fn new_from_bounds(bounds: Vec<T>) -> Option<RangeSet<T>> {
405        if bounds.len() % 2 == 1 {
406            return None;
407        }
408
409        let mut previous_max: Option<T> = None;
410        for range in bounds.chunks_exact(2) {
411            let (min, max) = (range[0], range[1]);
412            if min > max {
413                return None;
414            }
415            if let Some(previous_max) = previous_max {
416                // The ranges must be sorted and separated by at least one value.
417                if previous_max >= T::max_value() || min <= previous_max + T::one() {
418                    return None;
419                }
420            }
421            previous_max = Some(max);
422        }
423
424        Some(RangeSet(bounds))
425    }
426
427    /// Create a new instance that does not contain any value.
428    ///
429    /// # Example:
430    ///
431    /// ```
432    /// use irange::RangeSet;
433    ///
434    /// // Contains nothing
435    /// RangeSet::<i32>::empty();
436    /// ```
437    #[inline]
438    pub fn empty() -> RangeSet<T> {
439        RangeSet(vec![])
440    }
441
442    /// Create a new instance that contains all possible values.
443    ///
444    /// # Example:
445    ///
446    /// ```
447    /// use irange::RangeSet;
448    ///
449    /// // Contains all values that can be stored into a u8
450    /// // -> 0..=255
451    /// RangeSet::<u8>::total();
452    ///
453    /// // Contains all values that can be stored into a i16
454    /// // -> -32768..=32767
455    /// RangeSet::<i16>::total();
456    /// ```
457    #[inline]
458    pub fn total() -> RangeSet<T> {
459        RangeSet(vec![T::min_value(), T::max_value()])
460    }
461
462    /// Return `true` if it contains all the possible values.
463    ///
464    /// # Example:
465    ///
466    /// ```
467    /// use irange::RangeSet;
468    ///
469    /// let total = RangeSet::<u128>::total();
470    /// assert!(total.is_total());
471    ///
472    /// let range = RangeSet::<u32>::new_from_range(..=2);
473    /// assert!(!range.is_total());
474    /// ```
475    #[inline]
476    pub fn is_total(&self) -> bool {
477        self.0.len() >= 2 && self.0[0] == T::min_value() && self.0[1] >= T::max_value()
478    }
479
480    /// Return `true` if it does not contain any value.
481    ///
482    /// # Example:
483    ///
484    /// ```
485    /// use irange::RangeSet;
486    ///
487    /// let empty = RangeSet::<u128>::empty();
488    /// assert!(empty.is_empty());
489    ///
490    /// let range = RangeSet::<i64>::new_from_range(2..4);
491    /// assert!(!range.is_empty());
492    /// ```
493    #[inline]
494    pub fn is_empty(&self) -> bool {
495        self.0.is_empty()
496    }
497
498    /// Return `true` if it contains the given value.
499    ///
500    /// # Example:
501    ///
502    /// ```
503    /// use irange::RangeSet;
504    ///
505    /// let range = RangeSet::<i64>::new_from_range(2..4);
506    /// assert!(range.contains(2));
507    /// assert!(range.contains(3));
508    /// assert!(!range.contains(4));
509    /// ```
510    pub fn contains(&self, value: T) -> bool {
511        if self.is_empty() {
512            return false;
513        }
514        let first = *self.0.first().unwrap();
515        let last = *self.0.last().unwrap();
516        if value < first || value > last {
517            return false;
518        } else if value == first || value == last {
519            return true;
520        }
521
522        let position = self.0.partition_point(|&x| x < value);
523
524        self.0[position] == value || position % 2 != 0
525    }
526
527    /// Return `true` if it contains the given `RangeSet`.
528    ///
529    /// # Example:
530    ///
531    /// ```
532    /// use irange::RangeSet;
533    ///
534    /// let range1 = RangeSet::<i64>::new_from_range(11..90);
535    /// let range2 = RangeSet::<i64>::new_from_range(19..23);
536    ///
537    /// assert!(range1.contains_all(&range2));
538    /// assert!(!range2.contains_all(&range1));
539    /// ```
540    pub fn contains_all(&self, that: &RangeSet<T>) -> bool {
541        if self.is_total() || that.is_empty() {
542            return true;
543        }
544        if self.is_empty() || that.is_total() {
545            return false;
546        }
547
548        // Neither end of `that` can stick out of the span of `self`.
549        if that.0[0] < self.0[0] || that.0[that.0.len() - 1] > self.0[self.0.len() - 1] {
550            return false;
551        }
552
553        let mut self_i = 0;
554
555        for bounds in that.0.chunks_exact(2) {
556            let (that_min, that_max) = (bounds[0], bounds[1]);
557
558            // Skip the ranges of `self` that end before this one starts.
559            while self_i + 1 < self.0.len() && self.0[self_i + 1] < that_min {
560                self_i += 2;
561            }
562
563            if self_i + 1 >= self.0.len()
564                || self.0[self_i] > that_min
565                || self.0[self_i + 1] < that_max
566            {
567                return false;
568            }
569        }
570        true
571    }
572
573    /// Return the union with the given `RangeSet`.
574    ///
575    /// # Example:
576    ///
577    /// ```
578    /// use irange::RangeSet;
579    ///
580    /// let range1 = RangeSet::<i64>::new_from_range(2..4);
581    /// let range2 = RangeSet::<i64>::new_from_range(3..=5);
582    ///
583    /// // Contains 2..=5
584    /// let union = range1.union(&range2);
585    /// ```
586    pub fn union(&self, that: &RangeSet<T>) -> RangeSet<T> {
587        if self.is_empty() || that.is_total() {
588            return that.clone();
589        } else if that.is_empty() || self.is_total() {
590            return self.clone();
591        }
592
593        let mut new_range = Vec::with_capacity(self.0.len() + that.0.len());
594
595        let mut self_i = 0;
596        let mut that_i = 0;
597
598        // The range being built. It is written out once a range that does not touch it is
599        // found, since until then its upper bound can still grow.
600        let mut current: Option<(T, T)> = None;
601
602        while self_i + 1 < self.0.len() || that_i + 1 < that.0.len() {
603            // Take whichever side starts first, so the ranges are seen in order.
604            let (min, max) = if that_i + 1 < that.0.len()
605                && (self_i + 1 >= self.0.len() || self.0[self_i] > that.0[that_i])
606            {
607                that_i += 2;
608                (that.0[that_i - 2], that.0[that_i - 1])
609            } else {
610                self_i += 2;
611                (self.0[self_i - 2], self.0[self_i - 1])
612            };
613
614            match current {
615                // The range overlaps the current one or is adjacent to it: merge them.
616                Some((current_min, current_max))
617                    if min <= current_max
618                        || (current_max < T::max_value() && min <= current_max + T::one()) =>
619                {
620                    if max > current_max {
621                        current = Some((current_min, max));
622                    }
623                }
624                Some((current_min, current_max)) => {
625                    new_range.extend_from_slice(&[current_min, current_max]);
626                    current = Some((min, max));
627                }
628                None => current = Some((min, max)),
629            }
630        }
631
632        if let Some((current_min, current_max)) = current {
633            new_range.extend_from_slice(&[current_min, current_max]);
634        }
635
636        new_range.shrink_to_fit();
637        RangeSet(new_range)
638    }
639
640    /// Return `true` if there is common value with the given `RangeSet`.
641    ///
642    /// # Example:
643    ///
644    /// ```
645    /// use irange::RangeSet;
646    ///
647    /// let range1 = RangeSet::<i64>::new_from_range(2..4);
648    /// let range2 = RangeSet::<i64>::new_from_range(3..=5);
649    /// let range3 = RangeSet::<i64>::new_from_range(5..13);
650    ///
651    /// assert!(range1.has_intersection(&range2));
652    /// assert!(!range1.has_intersection(&range3));
653    /// assert!(range2.has_intersection(&range3));
654    /// ```
655    pub fn has_intersection(&self, that: &RangeSet<T>) -> bool {
656        let mut i = 0;
657        let mut j = 0;
658
659        while i + 1 < self.0.len() && j + 1 < that.0.len() {
660            let self_min = self.0[i];
661            let self_max = self.0[i + 1];
662            let that_min = that.0[j];
663            let that_max = that.0[j + 1];
664
665            if self_max < that_min {
666                i += 2;
667            } else if that_max < self_min {
668                j += 2;
669            } else {
670                return true;
671            }
672        }
673
674        false
675    }
676
677    /// Return the intersection with the given `RangeSet`.
678    ///
679    /// # Example:
680    ///
681    /// ```
682    /// use irange::RangeSet;
683    ///
684    /// let range1 = RangeSet::<i64>::new_from_range(2..4);
685    /// let range2 = RangeSet::<i64>::new_from_range(3..=5);
686    ///
687    /// // Contains 2..=3
688    /// let intersection = range1.intersection(&range2);
689    /// ```
690    pub fn intersection(&self, that: &RangeSet<T>) -> RangeSet<T> {
691        if self.is_empty() || that.is_empty() {
692            return RangeSet::empty();
693        } else if self.is_total() {
694            return that.clone();
695        } else if that.is_total() {
696            return self.clone();
697        }
698
699        let mut new_range = Vec::with_capacity(self.0.len() + that.0.len());
700
701        let mut i = 0;
702        let mut j = 0;
703
704        while i + 1 < self.0.len() && j + 1 < that.0.len() {
705            let self_min = self.0[i];
706            let self_max = self.0[i + 1];
707            let that_min = that.0[j];
708            let that_max = that.0[j + 1];
709
710            if self_max < that_min {
711                i += 2;
712            } else if that_max < self_min {
713                j += 2;
714            } else {
715                new_range.push(std::cmp::max(self_min, that_min));
716                new_range.push(std::cmp::min(self_max, that_max));
717
718                if self_max < that_max {
719                    i += 2;
720                } else {
721                    j += 2;
722                }
723            }
724        }
725
726        new_range.shrink_to_fit();
727        RangeSet(new_range)
728    }
729
730    /// Return the complement.
731    ///
732    /// # Example:
733    ///
734    /// ```
735    /// use irange::RangeSet;
736    ///
737    /// let range = RangeSet::<u8>::new_from_range(2..4);
738    ///
739    /// // Contains 0..=1 + 4..=255
740    /// range.complement();
741    /// ```
742    pub fn complement(&self) -> RangeSet<T> {
743        if self.is_empty() {
744            return Self::total();
745        } else if self.is_total() {
746            return Self::empty();
747        }
748
749        let mut new_range = Vec::with_capacity(self.0.len() + 2);
750
751        // The complement is made of the gaps between the ranges: everything below the first
752        // lower bound, the space between every upper bound and the next lower bound, and
753        // everything above the last upper bound.
754        let first = self.0[0];
755        if first > T::min_value() {
756            new_range.extend_from_slice(&[T::min_value(), first - T::one()]);
757        }
758
759        // Every `[upper bound, next lower bound]` pair, i.e. the bounds minus the first and
760        // the last one, describes exactly one gap.
761        let inner = if self.0.len() > 2 {
762            &self.0[1..self.0.len() - 1]
763        } else {
764            &[][..]
765        };
766        for gap in inner.chunks_exact(2) {
767            let (previous_max, next_min) = (gap[0], gap[1]);
768            // Always true for a canonical `RangeSet`; the checks only keep a hand-written one
769            // from overflowing.
770            if previous_max < T::max_value() && next_min > T::min_value() {
771                let (min, max) = (previous_max + T::one(), next_min - T::one());
772                if min <= max {
773                    new_range.extend_from_slice(&[min, max]);
774                }
775            }
776        }
777
778        let last = self.0[self.0.len() - 1];
779        if last < T::max_value() {
780            new_range.extend_from_slice(&[last + T::one(), T::max_value()]);
781        }
782
783        new_range.shrink_to_fit();
784        RangeSet(new_range)
785    }
786
787    /// Return the difference with the given `RangeSet`.
788    ///
789    /// # Example:
790    ///
791    /// ```
792    /// use irange::RangeSet;
793    ///
794    /// let range1 = RangeSet::<i64>::new_from_range(2..4);
795    /// let range2 = RangeSet::<i64>::new_from_range(3..=5);
796    ///
797    /// // Contains 2
798    /// let difference = range1.difference(&range2);
799    /// ```
800    pub fn difference(&self, that: &RangeSet<T>) -> RangeSet<T> {
801        if self.is_empty() || that.is_empty() {
802            return self.clone();
803        } else if that.is_total() {
804            return RangeSet::empty();
805        } else if self.is_total() {
806            return that.complement();
807        }
808
809        // A range of `self` is cut into at most one more piece than the number of ranges of
810        // `that` overlapping it, and those ranges are shared between at most two ranges of
811        // `self`, so the result never holds more than `self` and `that` together.
812        let mut new_range = Vec::with_capacity(self.0.len() + that.0.len());
813
814        // The first range of `that` that may still overlap the range of `self` being cut.
815        let mut that_i = 0;
816
817        for bounds in self.0.chunks_exact(2) {
818            let (mut min, max) = (bounds[0], bounds[1]);
819
820            // Skip the ranges of `that` that end before this one starts. They cannot overlap
821            // any later range of `self` either, so this stays linear overall.
822            while that_i + 1 < that.0.len() && that.0[that_i + 1] < min {
823                that_i += 2;
824            }
825
826            let mut j = that_i;
827            let mut covered = false;
828            while j + 1 < that.0.len() {
829                let (that_min, that_max) = (that.0[j], that.0[j + 1]);
830                if that_min > max {
831                    break;
832                }
833
834                // Keep what lies before the removed range.
835                if that_min > min {
836                    new_range.extend_from_slice(&[min, that_min - T::one()]);
837                }
838                if that_max >= max {
839                    covered = true;
840                    break;
841                }
842                // `that_max < max <= T::max_value()`, so this cannot overflow.
843                min = that_max + T::one();
844                j += 2;
845            }
846
847            // Keep what is left after the last removed range.
848            if !covered {
849                new_range.extend_from_slice(&[min, max]);
850            }
851        }
852
853        new_range.shrink_to_fit();
854        RangeSet(new_range)
855    }
856}
857
858impl<T: NumericInteger> Default for RangeSet<T> {
859    /// Return the empty set, like [`RangeSet::empty`].
860    #[inline]
861    fn default() -> RangeSet<T> {
862        RangeSet::empty()
863    }
864}
865
866impl<'a, T: NumericInteger> IntoIterator for &'a RangeSet<T> {
867    type Item = T;
868    type IntoIter = RangeSetIter<'a, T>;
869
870    /// Iterate in order over all the values contained, like [`RangeSet::iter`].
871    ///
872    /// # Example:
873    ///
874    /// ```
875    /// use irange::RangeSet;
876    ///
877    /// let range = RangeSet::new_from_range(2..=5);
878    ///
879    /// for value in &range {
880    ///     print!("{value} "); // 2 3 4 5
881    /// }
882    /// ```
883    #[inline]
884    fn into_iter(self) -> RangeSetIter<'a, T> {
885        self.iter()
886    }
887}
888
889impl<T: NumericInteger> FromIterator<AnyRange<T>> for RangeSet<T> {
890    /// Collect the given ranges into a single set, like [`RangeSet::new_from_ranges`].
891    ///
892    /// # Example:
893    ///
894    /// ```
895    /// use irange::range::AnyRange;
896    /// use irange::RangeSet;
897    ///
898    /// let range: RangeSet<i64> = [3..=4, 7..=8].into_iter().map(AnyRange::from).collect();
899    /// assert_eq!("[ 3..=4 7..=8 ]", range.to_string());
900    /// ```
901    fn from_iter<I: IntoIterator<Item = AnyRange<T>>>(iter: I) -> RangeSet<T> {
902        RangeSet::new_from_ranges(&iter.into_iter().collect::<Vec<_>>())
903    }
904}
905
906impl<T: NumericInteger> std::ops::BitOr<&RangeSet<T>> for &RangeSet<T> {
907    type Output = RangeSet<T>;
908
909    /// Compute the union, like [`RangeSet::union`].
910    ///
911    /// # Example:
912    ///
913    /// ```
914    /// use irange::RangeSet;
915    ///
916    /// let a = RangeSet::new_from_range(3..=4);
917    /// let b = RangeSet::new_from_range(7..=8);
918    /// assert_eq!("[ 3..=4 7..=8 ]", (&a | &b).to_string());
919    /// ```
920    #[inline]
921    fn bitor(self, that: &RangeSet<T>) -> RangeSet<T> {
922        self.union(that)
923    }
924}
925
926impl<T: NumericInteger> std::ops::BitAnd<&RangeSet<T>> for &RangeSet<T> {
927    type Output = RangeSet<T>;
928
929    /// Compute the intersection, like [`RangeSet::intersection`].
930    ///
931    /// # Example:
932    ///
933    /// ```
934    /// use irange::RangeSet;
935    ///
936    /// let a = RangeSet::new_from_range(3..=8);
937    /// let b = RangeSet::new_from_range(7..=9);
938    /// assert_eq!("[ 7..=8 ]", (&a & &b).to_string());
939    /// ```
940    #[inline]
941    fn bitand(self, that: &RangeSet<T>) -> RangeSet<T> {
942        self.intersection(that)
943    }
944}
945
946impl<T: NumericInteger> std::ops::Sub<&RangeSet<T>> for &RangeSet<T> {
947    type Output = RangeSet<T>;
948
949    /// Compute the difference, like [`RangeSet::difference`].
950    ///
951    /// # Example:
952    ///
953    /// ```
954    /// use irange::RangeSet;
955    ///
956    /// let a = RangeSet::new_from_range(3..=8);
957    /// let b = RangeSet::new_from_range(7..=9);
958    /// assert_eq!("[ 3..=6 ]", (&a - &b).to_string());
959    /// ```
960    #[inline]
961    fn sub(self, that: &RangeSet<T>) -> RangeSet<T> {
962        self.difference(that)
963    }
964}
965
966impl<T: NumericInteger> std::ops::Not for &RangeSet<T> {
967    type Output = RangeSet<T>;
968
969    /// Compute the complement, like [`RangeSet::complement`].
970    ///
971    /// # Example:
972    ///
973    /// ```
974    /// use irange::RangeSet;
975    ///
976    /// let a = RangeSet::<u8>::new_from_range(3..=254);
977    /// assert_eq!("[ 0..=2 255..=255 ]", (!&a).to_string());
978    /// ```
979    #[inline]
980    fn not(self) -> RangeSet<T> {
981        self.complement()
982    }
983}
984
985#[cfg(test)]
986mod tests {
987    use std::collections::{BTreeSet, HashSet};
988
989    use super::*;
990
991    macro_rules! test_empty_and_total_for_types {
992        ($($t:ty),*) => {
993            $(
994                let empty = RangeSet::<$t>::empty();
995                assert!(empty.is_empty());
996                assert!(!empty.is_total());
997
998                let total = RangeSet::<$t>::total();
999                assert!(!total.is_empty());
1000                assert!(total.is_total());
1001            )*
1002        };
1003    }
1004
1005    #[test]
1006    fn test_empty_and_total() -> Result<(), String> {
1007        test_empty_and_total_for_types!(
1008            u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize
1009        );
1010
1011        Ok(())
1012    }
1013
1014    #[test]
1015    fn test_new_from_range() -> Result<(), String> {
1016        assert_eq!(
1017            RangeSet::<u8>(vec![3, 4]),
1018            RangeSet::<u8>::new_from_range(3..5)
1019        );
1020
1021        assert_eq!(
1022            RangeSet::<u8>(vec![3, 5]),
1023            RangeSet::<u8>::new_from_range(3..=5)
1024        );
1025
1026        assert_eq!(
1027            RangeSet::<u8>(vec![0, 5]),
1028            RangeSet::<u8>::new_from_range(..=5)
1029        );
1030
1031        assert_eq!(
1032            RangeSet::<u8>(vec![2, 255]),
1033            RangeSet::<u8>::new_from_range(2..)
1034        );
1035
1036        assert_eq!(
1037            RangeSet::<u8>(vec![0, 255]),
1038            RangeSet::<u8>::new_from_range(..)
1039        );
1040
1041        Ok(())
1042    }
1043
1044    #[test]
1045    #[allow(clippy::reversed_empty_ranges)] // reversed ranges are used on purpose here
1046    fn test_new_from_ranges() -> Result<(), String> {
1047        assert_eq!(
1048            RangeSet(vec![3, 5, 9, 14]),
1049            RangeSet::new_from_ranges(&[AnyRange::from(3..=5), AnyRange::from(9..15)])
1050        );
1051
1052        assert_eq!(
1053            RangeSet(vec![3, 5, 9, 14]),
1054            RangeSet::new_from_ranges(&[AnyRange::from(9..15), AnyRange::from(3..=5)])
1055        );
1056
1057        assert_eq!(
1058            RangeSet(vec![3, 5, 9, 14]),
1059            RangeSet::new_from_ranges(&[
1060                AnyRange::from(9..15),
1061                AnyRange::from(23..18),
1062                AnyRange::from(3..=5),
1063                AnyRange::from(4..=4)
1064            ])
1065        );
1066
1067        assert_eq!(
1068            RangeSet(vec![3, 5, 9, 14]),
1069            RangeSet::new_from_ranges(&[
1070                AnyRange::from(9..15),
1071                AnyRange::from(23..18),
1072                AnyRange::from(3..=5)
1073            ])
1074        );
1075
1076        assert_eq!(
1077            RangeSet(vec![3, 255]),
1078            RangeSet::<u8>::new_from_ranges(&[AnyRange::from(4..), AnyRange::from(3..=5)])
1079        );
1080
1081        assert_eq!(
1082            RangeSet(vec![0, 5]),
1083            RangeSet::<u8>::new_from_ranges(&[AnyRange::from(..=4), AnyRange::from(3..=5)])
1084        );
1085
1086        assert_eq!(
1087            RangeSet::total(),
1088            RangeSet::new_from_ranges(&[AnyRange::from(..), AnyRange::from(3..=5)])
1089        );
1090
1091        assert_eq!(
1092            RangeSet::empty(),
1093            RangeSet::new_from_ranges(&[AnyRange::from(3..1), AnyRange::from(10..=5)])
1094        );
1095
1096        Ok(())
1097    }
1098
1099    #[test]
1100    fn test_contains_all() -> Result<(), String> {
1101        assert!(RangeSet::<u8>::empty().contains_all(&RangeSet::empty()));
1102        assert!(RangeSet::<u8>::total().contains_all(&RangeSet::empty()));
1103        assert!(!RangeSet::<u8>::empty().contains_all(&RangeSet::total()));
1104
1105        assert!(!RangeSet(vec![2, 44]).contains_all(&RangeSet(vec![56, 60])));
1106        assert!(!RangeSet(vec![56, 60]).contains_all(&RangeSet(vec![2, 44])));
1107        assert!(RangeSet(vec![56, 60]).contains_all(&RangeSet(vec![56, 60])));
1108        assert!(RangeSet(vec![56, 61]).contains_all(&RangeSet(vec![56, 61])));
1109        assert!(RangeSet(vec![55, 61]).contains_all(&RangeSet(vec![56, 60])));
1110
1111        assert!(RangeSet(vec![56, 60]).contains_all(&RangeSet(vec![57, 59])));
1112        assert!(RangeSet(vec![56, 60]).contains_all(&RangeSet(vec![57, 60])));
1113        assert!(RangeSet(vec![56, 60]).contains_all(&RangeSet(vec![56, 59])));
1114
1115        assert!(RangeSet(vec![19, 33]).contains_all(&RangeSet(vec![20, 21, 30, 32])));
1116        assert!(
1117            RangeSet(vec![19, 33, 53, 70]).contains_all(&RangeSet(vec![20, 21, 30, 32, 66, 69]))
1118        );
1119        assert!(
1120            !RangeSet(vec![19, 33, 53, 70]).contains_all(&RangeSet(vec![20, 21, 30, 32, 66, 71]))
1121        );
1122
1123        Ok(())
1124    }
1125
1126    #[test]
1127    fn test_iter_and_contains() -> Result<(), String> {
1128        let empty = RangeSet::<u8>::empty();
1129        assert_eq!(0, empty.iter().count());
1130        assert!(!empty.contains(0));
1131
1132        let total = RangeSet::<u8>::total();
1133        assert_eq!(256, total.iter().collect::<HashSet<_>>().len());
1134        assert!(total.iter().all(|v| total.contains(v)));
1135
1136        let range = RangeSet(vec![19, 33, 53, 70]);
1137        assert_eq!(33, range.iter().collect::<HashSet<_>>().len()); // (33 - 19 + 1) + (77 - 53 + 1) = 33
1138        assert!(range.iter().all(|v| range.contains(v)));
1139        assert!(!range.contains(34));
1140
1141        Ok(())
1142    }
1143
1144    #[test]
1145    fn test_union() -> Result<(), String> {
1146        assert!(RangeSet::<u8>::empty().union(&RangeSet::empty()).is_empty());
1147        assert!(RangeSet::<u8>::total().union(&RangeSet::empty()).is_total());
1148        assert!(RangeSet::<u8>::empty().union(&RangeSet::total()).is_total());
1149
1150        assert_eq!(
1151            vec![2, 44, 56, 60],
1152            RangeSet(vec![2, 44]).union(&RangeSet(vec![56, 60])).0
1153        );
1154
1155        assert_eq!(
1156            vec![0, 44],
1157            RangeSet(vec![2, 44]).union(&RangeSet(vec![0, 3])).0
1158        );
1159
1160        assert_eq!(
1161            vec![2, 48],
1162            RangeSet(vec![2, 44]).union(&RangeSet(vec![5, 48])).0
1163        );
1164
1165        assert_eq!(
1166            vec![2, 44],
1167            RangeSet(vec![2, 44]).union(&RangeSet(vec![2, 44])).0
1168        );
1169
1170        assert_eq!(
1171            vec![2, 44],
1172            RangeSet(vec![2, 44]).union(&RangeSet(vec![5, 20])).0
1173        );
1174
1175        assert_eq!(
1176            vec![2, 50],
1177            RangeSet(vec![2, 44]).union(&RangeSet(vec![45, 50])).0
1178        );
1179
1180        assert_eq!(
1181            vec![2, 44],
1182            RangeSet(vec![2, 44])
1183                .union(&RangeSet(vec![5, 20, 23, 40, 42, 43]))
1184                .0
1185        );
1186
1187        assert_eq!(
1188            vec![1, 44],
1189            RangeSet(vec![2, 44]).union(&RangeSet(vec![1, 2, 4, 5])).0
1190        );
1191
1192        assert_eq!(
1193            vec![0, 9, 11, 97],
1194            RangeSet(vec![0, 9, 11, 96])
1195                .union(&RangeSet(vec![97, 97]))
1196                .0
1197        );
1198
1199        let range1 = RangeSet::new_from_ranges(&[
1200            AnyRange::from(..=12),
1201            AnyRange::from(15..=15),
1202            AnyRange::from(18..),
1203        ]);
1204        let range2 = RangeSet::new_from_ranges(&[AnyRange::from(..=12), AnyRange::from(15..)]);
1205
1206        let range3 = RangeSet::new_from_ranges(&[AnyRange::from(..=12), AnyRange::from(15..)]);
1207        assert_eq!(range3, range1.union(&range2));
1208
1209        Ok(())
1210    }
1211
1212    #[test]
1213    fn test_intersection() -> Result<(), String> {
1214        assert!(RangeSet::<u32>::empty()
1215            .intersection(&RangeSet::empty())
1216            .is_empty());
1217        assert!(RangeSet::<u32>::total()
1218            .intersection(&RangeSet::empty())
1219            .is_empty());
1220        assert!(RangeSet::<u32>::empty()
1221            .intersection(&RangeSet::total())
1222            .is_empty());
1223        assert!(RangeSet::<u32>::total()
1224            .intersection(&RangeSet::total())
1225            .is_total());
1226
1227        assert_eq!(
1228            RangeSet::empty(),
1229            RangeSet(vec![2, 44]).intersection(&RangeSet(vec![56, 60]))
1230        );
1231
1232        assert_eq!(
1233            vec![2, 3],
1234            RangeSet(vec![2, 44]).intersection(&RangeSet(vec![0, 3])).0
1235        );
1236
1237        assert_eq!(
1238            vec![5, 44],
1239            RangeSet(vec![2, 44]).intersection(&RangeSet(vec![5, 48])).0
1240        );
1241
1242        assert_eq!(
1243            vec![2, 44],
1244            RangeSet(vec![2, 44]).intersection(&RangeSet(vec![2, 44])).0
1245        );
1246
1247        assert_eq!(
1248            vec![5, 20],
1249            RangeSet(vec![2, 44]).intersection(&RangeSet(vec![5, 20])).0
1250        );
1251        assert_eq!(
1252            vec![5, 20, 23, 40],
1253            RangeSet(vec![2, 44])
1254                .intersection(&RangeSet(vec![5, 20, 23, 40]))
1255                .0
1256        );
1257
1258        assert_eq!(
1259            vec![5, 20, 23, 40],
1260            RangeSet(vec![5, 20, 23, 40])
1261                .intersection(&RangeSet(vec![2, 44]))
1262                .0
1263        );
1264
1265        assert!(RangeSet(vec![99, 99])
1266            .intersection(&RangeSet(vec![i32::MIN, 98, 100, i32::MAX]))
1267            .is_empty());
1268        Ok(())
1269    }
1270
1271    #[test]
1272    fn test_complement() -> Result<(), String> {
1273        assert!(RangeSet::<u32>::total().complement().is_empty());
1274        assert!(RangeSet::<u32>::empty().complement().is_total());
1275
1276        assert_eq!(
1277            vec![0, 1, 45, u32::MAX],
1278            RangeSet(vec![2, 44]).complement().0
1279        );
1280
1281        assert_eq!(
1282            vec![45, i64::MAX],
1283            RangeSet(vec![i64::MIN, 44]).complement().0
1284        );
1285
1286        assert_eq!(
1287            vec![45, 238],
1288            RangeSet(vec![0, 44, 239, u32::MAX]).complement().0
1289        );
1290
1291        Ok(())
1292    }
1293
1294    #[cfg(feature = "serde")]
1295    macro_rules! serde_test {
1296        ($($t:ty),*) => {
1297            $(
1298                let range = RangeSet::<$t>::empty();
1299                let serialized = serde_json::to_string(&range).unwrap();
1300                let unserialized: RangeSet<$t> = serde_json::from_str(&serialized).unwrap();
1301                assert_eq!(range, unserialized);
1302
1303                let range = RangeSet::<$t>::total();
1304                let serialized = serde_json::to_string(&range).unwrap();
1305                let unserialized: RangeSet<$t> = serde_json::from_str(&serialized).unwrap();
1306                assert_eq!(range, unserialized);
1307
1308                let range =
1309                    RangeSet::<$t>::new_from_ranges(&[AnyRange::from(3..=4), AnyRange::from(7..9)]);
1310                let serialized = serde_json::to_string(&range).unwrap();
1311                let unserialized: RangeSet<$t> = serde_json::from_str(&serialized).unwrap();
1312                assert_eq!(range, unserialized);
1313            )*
1314        };
1315    }
1316
1317    #[test]
1318    #[cfg(feature = "serde")]
1319    fn serde_test() {
1320        serde_test!(u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize);
1321    }
1322
1323    /// A lower bound excluded from the range and equal to the maximum value: the range is empty.
1324    struct ExcludedMaxStart;
1325    impl RangeBounds<u8> for ExcludedMaxStart {
1326        fn start_bound(&self) -> Bound<&u8> {
1327            Bound::Excluded(&u8::MAX)
1328        }
1329        fn end_bound(&self) -> Bound<&u8> {
1330            Bound::Unbounded
1331        }
1332    }
1333
1334    /// A range with both bounds excluded, e.g. `(3, 7)` -> `4..=6`.
1335    struct ExcludedBothEnds(u8, u8);
1336    impl RangeBounds<u8> for ExcludedBothEnds {
1337        fn start_bound(&self) -> Bound<&u8> {
1338            Bound::Excluded(&self.0)
1339        }
1340        fn end_bound(&self) -> Bound<&u8> {
1341            Bound::Excluded(&self.1)
1342        }
1343    }
1344
1345    fn range_set_from_values(values: &[u8]) -> RangeSet<u8> {
1346        RangeSet::new_from_ranges(
1347            &values
1348                .iter()
1349                .map(|&value| AnyRange::from(value..=value))
1350                .collect::<Vec<_>>(),
1351        )
1352    }
1353
1354    /// Assert the internal representation is canonical: an even number of bounds, no inverted
1355    /// range and no two ranges that overlap or merely touch each other.
1356    fn assert_canonical(range: &RangeSet<u8>) {
1357        assert_eq!(
1358            0,
1359            range.0.len() % 2,
1360            "odd number of bounds in {:?}",
1361            range.0
1362        );
1363        for bounds in range.0.chunks(2) {
1364            assert!(
1365                bounds[0] <= bounds[1],
1366                "inverted range {}..={} in {:?}",
1367                bounds[0],
1368                bounds[1],
1369                range.0
1370            );
1371        }
1372        for pair in range.0.chunks(2).collect::<Vec<_>>().windows(2) {
1373            assert!(
1374                u16::from(pair[1][0]) > u16::from(pair[0][1]) + 1,
1375                "ranges {}..={} and {}..={} should have been merged in {:?}",
1376                pair[0][0],
1377                pair[0][1],
1378                pair[1][0],
1379                pair[1][1],
1380                range.0
1381            );
1382        }
1383    }
1384
1385    #[test]
1386    fn test_new_from_ranges_merges_adjacent_ranges() -> Result<(), String> {
1387        assert_eq!(
1388            RangeSet::<u8>::new_from_range(1..=4),
1389            RangeSet::<u8>::new_from_ranges(&[AnyRange::from(1..=2), AnyRange::from(3..=4)])
1390        );
1391
1392        assert_eq!(
1393            vec![1, 4],
1394            RangeSet::<u8>::new_from_ranges(&[AnyRange::from(3..=4), AnyRange::from(1..=2)]).0
1395        );
1396
1397        // A chain of ranges that only touch each other collapses into a single one.
1398        assert_eq!(
1399            vec![0, 9],
1400            RangeSet::<u8>::new_from_ranges(&[
1401                AnyRange::from(0..=2),
1402                AnyRange::from(3..=3),
1403                AnyRange::from(4..8),
1404                AnyRange::from(8..=9)
1405            ])
1406            .0
1407        );
1408
1409        // A range contained in the current one must not shrink it.
1410        assert_eq!(
1411            vec![0, 9],
1412            RangeSet::<u8>::new_from_ranges(&[AnyRange::from(0..=9), AnyRange::from(3..=4)]).0
1413        );
1414
1415        // A one value gap is preserved.
1416        assert_eq!(
1417            vec![0, 2, 4, 9],
1418            RangeSet::<u8>::new_from_ranges(&[AnyRange::from(0..=2), AnyRange::from(4..=9)]).0
1419        );
1420
1421        // Merging up to the maximum value must not overflow.
1422        assert_eq!(
1423            vec![250, 255],
1424            RangeSet::<u8>::new_from_ranges(&[
1425                AnyRange::from(250..=254),
1426                AnyRange::from(255..=255)
1427            ])
1428            .0
1429        );
1430        assert!(
1431            RangeSet::<u8>::new_from_ranges(&[AnyRange::from(..), AnyRange::from(200..=255)])
1432                .is_total()
1433        );
1434
1435        Ok(())
1436    }
1437
1438    #[test]
1439    fn test_complement_and_difference_with_adjacent_ranges() -> Result<(), String> {
1440        let range =
1441            RangeSet::<u8>::new_from_ranges(&[AnyRange::from(1..=2), AnyRange::from(3..=4)]);
1442        assert_canonical(&range);
1443
1444        let complement = range.complement();
1445        assert_canonical(&complement);
1446        assert_eq!(vec![0, 0, 5, 255], complement.0);
1447
1448        let range1 = RangeSet::<u8>::new_from_range(9..=12);
1449        let range2 =
1450            RangeSet::<u8>::new_from_ranges(&[AnyRange::from(11..=11), AnyRange::from(12..=17)]);
1451        let difference = range1.difference(&range2);
1452        assert_canonical(&difference);
1453        assert_eq!(vec![9, 10], difference.0);
1454
1455        let range =
1456            RangeSet::<u8>::new_from_ranges(&[AnyRange::from(3..=6), AnyRange::from(7..=11)]);
1457        assert!(range.contains_all(&RangeSet::new_from_range(3..=8)));
1458        assert!(range.contains_all(&RangeSet::new_from_range(3..=11)));
1459        assert!(!range.contains_all(&RangeSet::new_from_range(3..=12)));
1460
1461        Ok(())
1462    }
1463
1464    #[test]
1465    fn test_new_from_empty_range() -> Result<(), String> {
1466        assert!(RangeSet::<u8>::new_from_range(5..5).is_empty());
1467        assert!(RangeSet::<u8>::new_from_range(0..0).is_empty());
1468        assert!(RangeSet::<u8>::new_from_range(..0).is_empty());
1469        assert!(RangeSet::<u8>::new_from_range(ExcludedMaxStart).is_empty());
1470        assert!(RangeSet::<i32>::new_from_range(i32::MIN..i32::MIN).is_empty());
1471        assert!(RangeSet::<i8>::new_from_range(..i8::MIN).is_empty());
1472        assert!(RangeSet::<usize>::new_from_range(0..0).is_empty());
1473
1474        // An empty range must not be turned into the total range.
1475        assert!(!RangeSet::<u8>::new_from_range(0..0).is_total());
1476        assert!(!RangeSet::<i32>::new_from_range(i32::MIN..i32::MIN).is_total());
1477
1478        // An empty range is simply ignored when building from several ranges.
1479        assert!(RangeSet::<u8>::new_from_ranges(&[AnyRange::from(0..0)]).is_empty());
1480        assert_eq!(
1481            RangeSet::<u8>::new_from_range(7..=9),
1482            RangeSet::<u8>::new_from_ranges(&[AnyRange::from(0..0), AnyRange::from(7..=9)])
1483        );
1484
1485        // Excluded bounds that are not degenerate keep working.
1486        assert_eq!(
1487            vec![4, 6],
1488            RangeSet::<u8>::new_from_range(ExcludedBothEnds(3, 7)).0
1489        );
1490        assert_eq!(vec![0, 254], RangeSet::<u8>::new_from_range(..u8::MAX).0);
1491
1492        Ok(())
1493    }
1494
1495    #[test]
1496    fn test_malformed_range_set_does_not_panic() -> Result<(), String> {
1497        // A `RangeSet` can be built directly from its public field, so no operation may panic
1498        // on a malformed representation.
1499        for bounds in [
1500            vec![0u8],
1501            vec![1, 5, 9],
1502            vec![5, 3],
1503            vec![10, 20, 0, 5],
1504            // Bounds sitting on the ends of the type, where stepping outside of a range
1505            // would overflow.
1506            vec![1, 255, 3, 5],
1507            vec![255, 0],
1508            vec![0, 0, 255, 255],
1509            vec![255, 255, 0, 0],
1510        ] {
1511            let malformed = RangeSet::<u8>(bounds);
1512            let _ = malformed.is_total();
1513            let _ = malformed.is_empty();
1514            let _ = format!("{malformed}");
1515            let _ = malformed.contains(4);
1516            let _ = malformed.iter().take(512).count();
1517            let _ = malformed.complement();
1518            let _ = malformed.union(&RangeSet(vec![1, 2]));
1519            let _ = malformed.intersection(&RangeSet(vec![1, 2]));
1520            let _ = malformed.difference(&RangeSet(vec![1, 2]));
1521            let _ = malformed.has_intersection(&RangeSet(vec![1, 2]));
1522            let _ = malformed.contains_all(&RangeSet(vec![1, 2]));
1523            let _ = RangeSet(vec![1u8, 2]).contains_all(&malformed);
1524            let _ = RangeSet(vec![1u8, 2]).union(&malformed);
1525            let _ = RangeSet(vec![1u8, 2]).intersection(&malformed);
1526            let _ = RangeSet(vec![1u8, 2]).has_intersection(&malformed);
1527        }
1528
1529        Ok(())
1530    }
1531
1532    #[test]
1533    fn test_exhaustive_against_btree_set() -> Result<(), String> {
1534        const UNIVERSE: u8 = 7;
1535
1536        let subsets: Vec<(BTreeSet<u8>, RangeSet<u8>)> = (0..(1u32 << UNIVERSE))
1537            .map(|mask| {
1538                let values: Vec<u8> = (0..UNIVERSE)
1539                    .filter(|value| mask & (1 << value) != 0)
1540                    .collect();
1541                (
1542                    values.iter().copied().collect(),
1543                    range_set_from_values(&values),
1544                )
1545            })
1546            .collect();
1547
1548        for (values, range) in &subsets {
1549            assert_canonical(range);
1550            assert_eq!(*values, range.iter().collect::<BTreeSet<_>>());
1551            assert_eq!(values.is_empty(), range.is_empty());
1552
1553            let complement = range.complement();
1554            assert_canonical(&complement);
1555            assert_eq!(
1556                (0..=u8::MAX)
1557                    .filter(|v| !values.contains(v))
1558                    .collect::<BTreeSet<_>>(),
1559                complement.iter().collect::<BTreeSet<_>>()
1560            );
1561
1562            for value in 0..=UNIVERSE {
1563                assert_eq!(values.contains(&value), range.contains(value));
1564            }
1565        }
1566
1567        for (values1, range1) in &subsets {
1568            for (values2, range2) in &subsets {
1569                let union = range1.union(range2);
1570                assert_canonical(&union);
1571                assert_eq!(
1572                    values1.union(values2).copied().collect::<BTreeSet<_>>(),
1573                    union.iter().collect::<BTreeSet<_>>(),
1574                    "{range1} union {range2}"
1575                );
1576
1577                let intersection = range1.intersection(range2);
1578                assert_canonical(&intersection);
1579                assert_eq!(
1580                    values1
1581                        .intersection(values2)
1582                        .copied()
1583                        .collect::<BTreeSet<_>>(),
1584                    intersection.iter().collect::<BTreeSet<_>>(),
1585                    "{range1} intersection {range2}"
1586                );
1587
1588                let difference = range1.difference(range2);
1589                assert_canonical(&difference);
1590                assert_eq!(
1591                    values1
1592                        .difference(values2)
1593                        .copied()
1594                        .collect::<BTreeSet<_>>(),
1595                    difference.iter().collect::<BTreeSet<_>>(),
1596                    "{range1} difference {range2}"
1597                );
1598
1599                assert_eq!(
1600                    !values1.is_disjoint(values2),
1601                    range1.has_intersection(range2),
1602                    "{range1} has_intersection {range2}"
1603                );
1604                assert_eq!(
1605                    values2.is_subset(values1),
1606                    range1.contains_all(range2),
1607                    "{range1} contains_all {range2}"
1608                );
1609
1610                // Equal sets must have equal representations, otherwise `Eq` and `Hash` lie.
1611                if values1 == values2 {
1612                    assert_eq!(range1, range2);
1613                }
1614            }
1615        }
1616
1617        Ok(())
1618    }
1619
1620    #[test]
1621    fn test_randomized_against_btree_set_over_the_whole_universe() -> Result<(), String> {
1622        // `test_exhaustive_against_btree_set` only uses small values, so it never exercises the
1623        // ranges that touch `u8::MIN` or `u8::MAX`. These sets are drawn from the whole universe
1624        // and are dense enough to produce ranges at both ends.
1625        let mut state = 0x2545_f491_4f6c_dd1du64;
1626        let mut next = move || {
1627            state ^= state << 13;
1628            state ^= state >> 7;
1629            state ^= state << 17;
1630            state
1631        };
1632
1633        let subsets: Vec<(BTreeSet<u8>, RangeSet<u8>)> = (0..200)
1634            .map(|_| {
1635                // A varying density so that both sparse sets and sets spanning the whole
1636                // universe are covered.
1637                let density = (next() % 100) as u8;
1638                let values: Vec<u8> = (0..=u8::MAX)
1639                    .filter(|_| (next() % 100) as u8 <= density)
1640                    .collect();
1641                (
1642                    values.iter().copied().collect(),
1643                    range_set_from_values(&values),
1644                )
1645            })
1646            .collect();
1647
1648        for (values, range) in &subsets {
1649            assert_canonical(range);
1650            assert_eq!(*values, range.iter().collect::<BTreeSet<_>>());
1651
1652            let complement = range.complement();
1653            assert_canonical(&complement);
1654            assert_eq!(
1655                (0..=u8::MAX)
1656                    .filter(|value| !values.contains(value))
1657                    .collect::<BTreeSet<_>>(),
1658                complement.iter().collect::<BTreeSet<_>>(),
1659                "complement of {range}"
1660            );
1661        }
1662
1663        for (values1, range1) in &subsets {
1664            for (values2, range2) in &subsets {
1665                let union = range1.union(range2);
1666                assert_canonical(&union);
1667                assert_eq!(
1668                    values1.union(values2).copied().collect::<BTreeSet<_>>(),
1669                    union.iter().collect::<BTreeSet<_>>(),
1670                    "{range1} union {range2}"
1671                );
1672
1673                let intersection = range1.intersection(range2);
1674                assert_canonical(&intersection);
1675                assert_eq!(
1676                    values1
1677                        .intersection(values2)
1678                        .copied()
1679                        .collect::<BTreeSet<_>>(),
1680                    intersection.iter().collect::<BTreeSet<_>>(),
1681                    "{range1} intersection {range2}"
1682                );
1683
1684                let difference = range1.difference(range2);
1685                assert_canonical(&difference);
1686                assert_eq!(
1687                    values1
1688                        .difference(values2)
1689                        .copied()
1690                        .collect::<BTreeSet<_>>(),
1691                    difference.iter().collect::<BTreeSet<_>>(),
1692                    "{range1} difference {range2}"
1693                );
1694
1695                assert_eq!(
1696                    !values1.is_disjoint(values2),
1697                    range1.has_intersection(range2),
1698                    "{range1} has_intersection {range2}"
1699                );
1700                assert_eq!(
1701                    values2.is_subset(values1),
1702                    range1.contains_all(range2),
1703                    "{range1} contains_all {range2}"
1704                );
1705            }
1706        }
1707
1708        Ok(())
1709    }
1710
1711    #[test]
1712    fn test_new_from_bounds_validation() -> Result<(), String> {
1713        assert_eq!(
1714            Some(RangeSet::<u8>::empty()),
1715            RangeSet::<u8>::new_from_bounds(vec![])
1716        );
1717        assert_eq!(
1718            Some(RangeSet::<u8>::new_from_range(2..=5)),
1719            RangeSet::<u8>::new_from_bounds(vec![2, 5])
1720        );
1721        assert_eq!(
1722            Some(RangeSet::<u8>::total()),
1723            RangeSet::<u8>::new_from_bounds(vec![0, 255])
1724        );
1725        assert_eq!(
1726            Some(RangeSet::<u8>(vec![2, 5, 7, 9])),
1727            RangeSet::<u8>::new_from_bounds(vec![2, 5, 7, 9])
1728        );
1729
1730        // Odd number of bounds.
1731        assert_eq!(None, RangeSet::<u8>::new_from_bounds(vec![0]));
1732        assert_eq!(None, RangeSet::<u8>::new_from_bounds(vec![0, 5, 7]));
1733        // Inverted range.
1734        assert_eq!(None, RangeSet::<u8>::new_from_bounds(vec![5, 3]));
1735        // Unsorted ranges.
1736        assert_eq!(None, RangeSet::<u8>::new_from_bounds(vec![10, 20, 0, 5]));
1737        // Overlapping ranges.
1738        assert_eq!(None, RangeSet::<u8>::new_from_bounds(vec![0, 5, 4, 9]));
1739        // Adjacent ranges, they should have been merged.
1740        assert_eq!(None, RangeSet::<u8>::new_from_bounds(vec![0, 5, 6, 9]));
1741        // A range starting after the maximum value cannot exist.
1742        assert_eq!(
1743            None,
1744            RangeSet::<u8>::new_from_bounds(vec![0, 255, 255, 255])
1745        );
1746
1747        Ok(())
1748    }
1749
1750    #[test]
1751    #[cfg(feature = "serde")]
1752    fn serde_rejects_malformed_range_set() {
1753        assert!(serde_json::from_str::<RangeSet<u8>>("[]").is_ok());
1754        assert!(serde_json::from_str::<RangeSet<u8>>("[0,5]").is_ok());
1755        assert!(serde_json::from_str::<RangeSet<u8>>("[0,5,7,9]").is_ok());
1756
1757        // Odd number of bounds.
1758        assert!(serde_json::from_str::<RangeSet<u8>>("[0]").is_err());
1759        assert!(serde_json::from_str::<RangeSet<u8>>("[0,5,7]").is_err());
1760        // Inverted range.
1761        assert!(serde_json::from_str::<RangeSet<u8>>("[5,3]").is_err());
1762        // Unsorted ranges.
1763        assert!(serde_json::from_str::<RangeSet<u8>>("[10,20,0,5]").is_err());
1764        // Overlapping ranges.
1765        assert!(serde_json::from_str::<RangeSet<u8>>("[0,5,4,9]").is_err());
1766        // Adjacent ranges that should have been merged.
1767        assert!(serde_json::from_str::<RangeSet<u8>>("[0,5,6,9]").is_err());
1768    }
1769}