range_collections/
range_set.rs

1#![deny(missing_docs)]
2#![allow(clippy::needless_lifetimes)]
3
4//! A set of non-overlapping ranges
5use crate::merge_state::{
6    BoolOpMergeState, InPlaceMergeState, InPlaceMergeStateRef, MergeStateMut, SmallVecMergeState,
7};
8use binary_merge::{MergeOperation, MergeState};
9use core::cmp::Ordering;
10use core::fmt::Debug;
11use core::ops::{
12    BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Bound, Not, Range, RangeFrom,
13    RangeTo, Sub, SubAssign,
14};
15use ref_cast::{ref_cast_custom, RefCastCustom};
16use smallvec::{Array, SmallVec};
17use std::borrow::Borrow;
18use std::num::*;
19use std::ops::{Deref, RangeBounds, RangeFull};
20#[cfg(feature = "serde")]
21use {
22    core::{fmt, marker::PhantomData},
23    serde::{
24        de::{Deserialize, Deserializer, SeqAccess, Visitor},
25        ser::{Serialize, SerializeSeq, Serializer},
26    },
27};
28
29/// # A set of non-overlapping ranges
30///
31/// ```
32/// # use range_collections::{RangeSet, RangeSet2};
33/// let mut a: RangeSet2<i32> = RangeSet::from(10..);
34/// let b: RangeSet2<i32> = RangeSet::from(1..5);
35///
36/// a |= b;
37/// let r = !a;
38/// ```
39///
40/// A data structure to represent a set of non-overlapping ranges of element type `T: RangeSetEntry`. It uses a `SmallVec<T>`
41/// of sorted boundaries internally.
42///
43/// It can represent not just finite ranges but also ranges with unbounded end. Because it can represent
44/// infinite ranges, it can also represent the set of all elements, and therefore all boolean operations including negation.
45///
46/// Adjacent ranges will be merged.
47///
48/// It provides very fast operations for set operations (&, |, ^) as well as for intersection tests (is_disjoint, is_subset).
49///
50/// In addition to the fast set operations that produce a new range set, it also supports the equivalent in-place operations.
51///
52/// # Complexity
53///
54/// Complexity is given separately for the number of comparisons and the number of copies, since sometimes you have
55/// a comparison operation that is basically free (any of the primitive types), whereas sometimes you have a comparison
56/// operation that is many orders of magnitude more expensive than a copy (long strings, arbitrary precision integers, ...)
57///
58/// ## Number of comparisons
59///
60/// |operation    | best      | worst     | remark
61/// |-------------|-----------|-----------|--------
62/// |negation     | 1         | O(N)      |
63/// |union        | O(log(N)) | O(N)      | binary merge
64/// |intersection | O(log(N)) | O(N)      | binary merge
65/// |difference   | O(log(N)) | O(N)      | binary merge
66/// |xor          | O(log(N)) | O(N)      | binary merge
67/// |membership   | O(log(N)) | O(log(N)) | binary search
68/// |is_disjoint  | O(log(N)) | O(N)      | binary merge with cutoff
69/// |is_subset    | O(log(N)) | O(N)      | binary merge with cutoff
70///
71/// ## Number of copies
72///
73/// For creating new sets, obviously there needs to be at least one copy for each element of the result set, so the
74/// complexity is always O(N). For in-place operations it gets more interesting. In case the number of elements of
75/// the result being identical to the number of existing elements, there will be no copies and no allocations.
76///
77/// E.g. if the result just has some of the ranges of the left hand side extended or truncated, but the same number of boundaries,
78/// there will be no allocations and no copies except for the changed boundaries themselves.
79///
80/// If the result has fewer boundaries than then lhs, there will be some copying but no allocations. Only if the result
81/// is larger than the capacity of the underlying vector of the lhs will there be allocations.
82///
83/// |operation    | best      | worst     |
84/// |-------------|-----------|-----------|
85/// |negation     | 1         | 1         |
86/// |union        | 1         | O(N)      |
87/// |intersection | 1         | O(N)      |
88/// |difference   | 1         | O(N)      |
89/// |xor          | 1         | O(N)      |
90///
91/// # Testing
92///
93/// Testing is done by some simple smoke tests as well as quickcheck tests of the algebraic properties of the boolean operations.
94pub struct RangeSet<A: Array>(SmallVec<A>);
95
96impl<T, A: Array<Item = T>> Default for RangeSet<A> {
97    fn default() -> Self {
98        Self(Default::default())
99    }
100}
101
102impl<T, A: Array<Item = T>> Deref for RangeSet<A> {
103    type Target = RangeSetRef<T>;
104
105    fn deref(&self) -> &Self::Target {
106        RangeSetRef::new_unchecked_impl(&self.0)
107    }
108}
109
110impl<T, A: Array<Item = T>> AsRef<RangeSetRef<T>> for RangeSet<A> {
111    fn as_ref(&self) -> &RangeSetRef<T> {
112        RangeSetRef::new_unchecked_impl(&self.0)
113    }
114}
115
116impl<T, A: Array<Item = T>> Borrow<RangeSetRef<T>> for RangeSet<A> {
117    fn borrow(&self) -> &RangeSetRef<T> {
118        RangeSetRef::new_unchecked_impl(&self.0)
119    }
120}
121
122/// Range that can be part of a range set
123///
124/// Start boundaries are always inclusive, end boundaries are exclusive.
125/// Therefore some ranges types are not going to appear in a range set.
126#[derive(Clone)]
127pub enum RangeSetRange<T> {
128    /// Closed range
129    Range(Range<T>),
130    /// Range with unbounded end
131    RangeFrom(RangeFrom<T>),
132}
133
134impl<T: Clone> RangeSetRange<&T> {
135    /// Maps a `RangeSetRange<&T>` to a `RangeSetRange<T>` by cloning start and end.
136    pub fn cloned(&self) -> RangeSetRange<T> {
137        match self {
138            RangeSetRange::Range(r) => RangeSetRange::Range(r.start.clone()..r.end.clone()),
139            RangeSetRange::RangeFrom(r) => RangeSetRange::RangeFrom(r.start.clone()..),
140        }
141    }
142}
143
144impl<T> From<Range<T>> for RangeSetRange<T> {
145    fn from(r: Range<T>) -> Self {
146        RangeSetRange::Range(r)
147    }
148}
149
150impl<T> From<RangeFrom<T>> for RangeSetRange<T> {
151    fn from(r: RangeFrom<T>) -> Self {
152        RangeSetRange::RangeFrom(r)
153    }
154}
155
156impl<T: RangeSetEntry, A: Array<Item = T>> From<RangeSetRange<T>> for RangeSet<A> {
157    fn from(value: RangeSetRange<T>) -> Self {
158        match value {
159            RangeSetRange::Range(r) => RangeSet::from(r),
160            RangeSetRange::RangeFrom(r) => RangeSet::from(r),
161        }
162    }
163}
164
165impl<T: Debug> Debug for RangeSetRange<T> {
166    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
167        match self {
168            RangeSetRange::Range(r) => r.fmt(f),
169            RangeSetRange::RangeFrom(r) => r.fmt(f),
170        }
171    }
172}
173
174impl<T> RangeBounds<T> for RangeSetRange<T> {
175    fn start_bound(&self) -> Bound<&T> {
176        match self {
177            RangeSetRange::Range(r) => r.start_bound(),
178            RangeSetRange::RangeFrom(r) => r.start_bound(),
179        }
180    }
181
182    fn end_bound(&self) -> Bound<&T> {
183        match self {
184            RangeSetRange::Range(r) => r.end_bound(),
185            RangeSetRange::RangeFrom(r) => r.end_bound(),
186        }
187    }
188}
189
190impl<A: Array> Clone for RangeSet<A>
191where
192    A::Item: Clone,
193{
194    fn clone(&self) -> Self {
195        Self(self.0.clone())
196    }
197}
198
199impl<A: Array, R: AsRef<RangeSetRef<A::Item>>> PartialEq<R> for RangeSet<A>
200where
201    A::Item: RangeSetEntry,
202{
203    fn eq(&self, that: &R) -> bool {
204        self.boundaries() == that.as_ref().boundaries()
205    }
206}
207
208impl<A: Array> Eq for RangeSet<A> where A::Item: Eq + RangeSetEntry {}
209
210/// A range set that stores up to 2 boundaries inline
211pub type RangeSet2<T> = RangeSet<[T; 2]>;
212
213impl<T: Debug, A: Array<Item = T>> Debug for RangeSet<A> {
214    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
215        write!(f, "RangeSet{{")?;
216        for (i, r) in self.iter().enumerate() {
217            if i > 0 {
218                write!(f, ", ")?;
219            }
220            write!(f, "{r:?}")?;
221        }
222        write!(f, "}}")
223    }
224}
225
226/// Iterator for the ranges in a range set
227pub struct Iter<'a, T>(&'a [T]);
228
229impl<'a, T> Iterator for Iter<'a, T> {
230    type Item = RangeSetRange<&'a T>;
231
232    fn next(&mut self) -> Option<Self::Item> {
233        let bounds = self.0;
234        if !bounds.is_empty() {
235            Some(if bounds.len() == 1 {
236                self.0 = &bounds[1..];
237                RangeSetRange::from(&bounds[0]..)
238            } else {
239                self.0 = &bounds[2..];
240                RangeSetRange::from(&bounds[0]..&bounds[1])
241            })
242        } else {
243            None
244        }
245    }
246}
247
248/// A reference to a range set
249#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, RefCastCustom)]
250#[repr(transparent)]
251pub struct RangeSetRef<T>([T]);
252
253impl<T> Default for &RangeSetRef<T> {
254    fn default() -> Self {
255        RangeSetRef::new_unchecked_impl(&[])
256    }
257}
258
259impl<T> RangeSetRef<T> {
260    /// Create a new range set reference for an empty range set
261    pub const fn empty() -> &'static Self {
262        RangeSetRef::new_unchecked_impl(&[])
263    }
264
265    /// Create a new range set reference for a single boundary change
266    ///
267    /// This produces a RangeSetRef that goes from off before `value` to on at
268    /// *and after* `value`.
269    pub const fn single(value: &T) -> &Self {
270        RangeSetRef::new_unchecked_impl(std::slice::from_ref(value))
271    }
272
273    /// Create a new range set reference
274    ///
275    /// This performs a check that the boundaries are strictly sorted.
276    /// If you want to avoid this check, use `new_unchecked`
277    /// (behind a feature flag because it is unsafe)
278    pub fn new(boundaries: &[T]) -> Option<&Self>
279    where
280        T: Ord,
281    {
282        if is_strictly_sorted(boundaries) {
283            Some(Self::new_unchecked_impl(boundaries))
284        } else {
285            None
286        }
287    }
288
289    /// Split this range set into two parts `left`, `right` at position `at`,
290    /// so that `left` is identical to `self` for all `x < at`
291    /// and `right` is identical to `self` for all `x >= at`.
292    ///
293    /// More precisely:
294    ///   contains(left, x) == contains(ranges, x) for x < at
295    ///   contains(right, x) == contains(ranges, x) for x >= at
296    ///
297    /// This is not the same as limiting the ranges to the left or right of
298    /// `at`, but it is much faster. It requires just a binary search and no
299    /// allocations.
300    pub fn split(&self, at: T) -> (&Self, &Self)
301    where
302        T: Ord,
303    {
304        let (left, right) = split(&self.0, at);
305        (
306            Self::new_unchecked_impl(left),
307            Self::new_unchecked_impl(right),
308        )
309    }
310
311    /// Create a new range set reference without checking that the boundaries are
312    /// strictly sorted.
313    #[cfg(feature = "new_unchecked")]
314    pub const fn new_unchecked(boundaries: &[T]) -> &Self {
315        Self::new_unchecked_impl(boundaries)
316    }
317
318    #[ref_cast_custom]
319    const fn new_unchecked_impl(boundaries: &[T]) -> &Self;
320
321    /// The boundaries of the range set, guaranteed to be strictly sorted
322    pub const fn boundaries(&self) -> &[T] {
323        &self.0
324    }
325
326    /// true if the value is contained in the range set
327    pub fn contains(&self, value: &T) -> bool
328    where
329        T: Ord,
330    {
331        match self.boundaries().binary_search(value) {
332            Ok(index) => !is_odd(index),
333            Err(index) => is_odd(index),
334        }
335    }
336
337    /// true if the range set is empty
338    pub const fn is_empty(&self) -> bool {
339        self.boundaries().is_empty()
340    }
341
342    /// true if the range set contains all values
343    pub fn is_all(&self) -> bool
344    where
345        T: RangeSetEntry,
346    {
347        self.boundaries().len() == 1 && self.boundaries()[0].is_min_value()
348    }
349
350    /// true if this range set intersects from another range set
351    ///
352    /// This is just the opposite of `is_disjoint`, but is provided for
353    /// better discoverability.
354    pub fn intersects(&self, that: &RangeSetRef<T>) -> bool
355    where
356        T: Ord,
357    {
358        !self.is_disjoint(that)
359    }
360
361    /// true if this range set is disjoint from another range set
362    pub fn is_disjoint(&self, that: &RangeSetRef<T>) -> bool
363    where
364        T: Ord,
365    {
366        !RangeSetBoolOpMergeState::merge(self.boundaries(), that.boundaries(), IntersectionOp::<0>)
367    }
368
369    /// true if this range set is a superset of another range set
370    ///
371    /// A range set is considered to be a superset of itself
372    pub fn is_subset(&self, that: &RangeSetRef<T>) -> bool
373    where
374        T: Ord,
375    {
376        !RangeSetBoolOpMergeState::merge(self.boundaries(), that.boundaries(), DiffOp::<0>)
377    }
378
379    /// true if this range set is a subset of another range set
380    ///
381    /// A range set is considered to be a subset of itself
382    pub fn is_superset(&self, that: &RangeSetRef<T>) -> bool
383    where
384        T: Ord,
385    {
386        !RangeSetBoolOpMergeState::merge(that.boundaries(), self.boundaries(), DiffOp::<0>)
387    }
388
389    /// iterate over all ranges in this range set
390    pub fn iter(&self) -> Iter<T> {
391        Iter(self.boundaries())
392    }
393
394    /// intersection
395    pub fn intersection<A>(&self, that: &RangeSetRef<T>) -> RangeSet<A>
396    where
397        A: Array<Item = T>,
398        T: Ord + Clone,
399    {
400        RangeSet::new_unchecked_impl(VecMergeState::merge(
401            self.boundaries(),
402            that.boundaries(),
403            IntersectionOp::<{ usize::MAX }>,
404        ))
405    }
406
407    /// union
408    pub fn union<A>(&self, that: &RangeSetRef<T>) -> RangeSet<A>
409    where
410        A: Array<Item = T>,
411        T: Ord + Clone,
412    {
413        RangeSet::new_unchecked_impl(VecMergeState::merge(
414            self.boundaries(),
415            that.boundaries(),
416            UnionOp,
417        ))
418    }
419
420    /// difference
421    pub fn difference<A>(&self, that: &RangeSetRef<T>) -> RangeSet<A>
422    where
423        A: Array<Item = T>,
424        T: Ord + Clone,
425    {
426        RangeSet::new_unchecked_impl(VecMergeState::merge(
427            self.boundaries(),
428            that.boundaries(),
429            DiffOp::<{ usize::MAX }>,
430        ))
431    }
432
433    /// symmetric difference (xor)
434    pub fn symmetric_difference<A>(&self, that: &RangeSetRef<T>) -> RangeSet<A>
435    where
436        A: Array<Item = T>,
437        T: Ord + Clone,
438    {
439        RangeSet::new_unchecked_impl(VecMergeState::merge(
440            self.boundaries(),
441            that.boundaries(),
442            XorOp,
443        ))
444    }
445}
446
447#[cfg(feature = "rkyv")]
448impl<T> Deref for ArchivedRangeSet<T> {
449    type Target = RangeSetRef<T>;
450
451    fn deref(&self) -> &Self::Target {
452        RangeSetRef::new_unchecked(&self.0)
453    }
454}
455
456#[cfg(feature = "rkyv")]
457impl<T> AsRef<RangeSetRef<T>> for ArchivedRangeSet<T> {
458    fn as_ref(&self) -> &RangeSetRef<T> {
459        RangeSetRef::new_unchecked(&self.0)
460    }
461}
462
463#[cfg(feature = "rkyv")]
464impl<T> Borrow<RangeSetRef<T>> for ArchivedRangeSet<T> {
465    fn borrow(&self) -> &RangeSetRef<T> {
466        RangeSetRef::new_unchecked(&self.0)
467    }
468}
469
470/// trait for types that can be entries of range sets
471///
472/// they must have an order and a minimum value.
473pub trait RangeSetEntry: Ord {
474    /// the minimum value for this type
475    fn min_value() -> Self;
476
477    /// checks if this is the minimum value
478    ///
479    /// this is to be able to check for minimum without having to create a value
480    fn is_min_value(&self) -> bool;
481}
482
483macro_rules! entry_instance {
484    ($t:tt) => {
485        impl RangeSetEntry for $t {
486
487            fn min_value() -> Self {
488                $t::MIN
489            }
490
491            fn is_min_value(&self) -> bool {
492                *self == $t::MIN
493            }
494        }
495    };
496    ($t:tt, $($rest:tt),+) => {
497        entry_instance!($t);
498        entry_instance!($( $rest ),*);
499    }
500}
501
502macro_rules! non_zero_u_entry_instance {
503    ($t:tt) => {
504        impl RangeSetEntry for $t {
505
506            fn min_value() -> Self {
507                $t::new(1).unwrap()
508            }
509
510            fn is_min_value(&self) -> bool {
511                *self == $t::new(1).unwrap()
512            }
513        }
514    };
515    ($t:tt, $($rest:tt),+) => {
516        non_zero_u_entry_instance!($t);
517        non_zero_u_entry_instance!($( $rest ),*);
518    }
519}
520
521entry_instance!(u8, u16, u32, u64, u128, usize);
522entry_instance!(i8, i16, i32, i64, i128, isize);
523non_zero_u_entry_instance!(
524    NonZeroU8,
525    NonZeroU16,
526    NonZeroU32,
527    NonZeroU64,
528    NonZeroU128,
529    NonZeroUsize
530);
531
532impl<T: Ord> RangeSetEntry for Option<T> {
533    fn min_value() -> Self {
534        None
535    }
536
537    fn is_min_value(&self) -> bool {
538        self.is_none()
539    }
540}
541
542impl RangeSetEntry for String {
543    fn min_value() -> Self {
544        "".to_owned()
545    }
546
547    fn is_min_value(&self) -> bool {
548        self.is_empty()
549    }
550}
551
552impl RangeSetEntry for &str {
553    fn min_value() -> Self {
554        ""
555    }
556
557    fn is_min_value(&self) -> bool {
558        self.is_empty()
559    }
560}
561
562impl<T: Ord> RangeSetEntry for Vec<T> {
563    fn min_value() -> Self {
564        Vec::new()
565    }
566
567    fn is_min_value(&self) -> bool {
568        self.is_empty()
569    }
570}
571
572impl<T: Ord> RangeSetEntry for &[T] {
573    fn min_value() -> Self {
574        &[]
575    }
576
577    fn is_min_value(&self) -> bool {
578        self.is_empty()
579    }
580}
581
582impl<T, A: Array<Item = T>> RangeSet<A> {
583    /// create a new range set from the given boundaries
584    ///
585    /// This performs a check that the boundaries are strictly sorted.
586    /// If you want to avoid this check, use `new_unchecked`
587    /// (behind a feature flag because it is unsafe)
588    pub fn new(boundaries: SmallVec<A>) -> Option<Self>
589    where
590        A::Item: Ord,
591    {
592        if is_strictly_sorted(boundaries.as_ref()) {
593            Some(Self::new_unchecked_impl(boundaries))
594        } else {
595            None
596        }
597    }
598
599    /// Create a new range set reference without checking that the boundaries are
600    /// strictly sorted.
601    #[cfg(feature = "new_unchecked")]
602    pub fn new_unchecked(boundaries: SmallVec<A>) -> Self {
603        Self::new_unchecked_impl(boundaries)
604    }
605
606    /// note that this is private since it does not check the invariants!
607    fn new_unchecked_impl(boundaries: SmallVec<A>) -> Self {
608        RangeSet(boundaries)
609    }
610
611    /// iterate over all ranges in this range set
612    pub fn iter(&self) -> Iter<T> {
613        Iter(self.0.as_ref())
614    }
615
616    /// get the boundaries in this range set as a SmallVec
617    pub fn into_inner(self) -> SmallVec<A> {
618        self.0
619    }
620}
621
622impl<T: RangeSetEntry, A: Array<Item = T>> RangeSet<A> {
623    fn from_range_until(a: T) -> Self {
624        let mut t = SmallVec::new();
625        if !a.is_min_value() {
626            t.push(T::min_value());
627            t.push(a);
628        }
629        Self::new_unchecked_impl(t)
630    }
631    fn from_range_from(a: T) -> Self {
632        let mut t = SmallVec::new();
633        t.push(a);
634        Self::new_unchecked_impl(t)
635    }
636    /// the empty range set
637    pub fn empty() -> Self {
638        Self(SmallVec::new())
639    }
640    /// a range set containing all values
641    pub fn all() -> Self {
642        Self::from_range_from(T::min_value())
643    }
644}
645
646impl<T: RangeSetEntry + Clone, A: Array<Item = T>> RangeSet<A> {
647    /// intersection in place
648    pub fn intersection_with(&mut self, that: &RangeSetRef<T>) {
649        InPlaceMergeStateRef::merge(
650            &mut self.0,
651            &that.boundaries(),
652            IntersectionOp::<{ usize::MAX }>,
653        );
654    }
655    /// union in place
656    pub fn union_with(&mut self, that: &RangeSetRef<T>) {
657        InPlaceMergeStateRef::merge(&mut self.0, &that.boundaries(), UnionOp);
658    }
659    /// difference in place
660    pub fn difference_with(&mut self, that: &RangeSetRef<T>) {
661        InPlaceMergeStateRef::merge(&mut self.0, &that.boundaries(), DiffOp::<{ usize::MAX }>);
662    }
663    /// symmetric difference in place (xor)
664    pub fn symmetric_difference_with(&mut self, that: &RangeSetRef<T>) {
665        InPlaceMergeStateRef::merge(&mut self.0, &that.boundaries(), XorOp);
666    }
667}
668
669impl<T: RangeSetEntry, A: Array<Item = T>> From<bool> for RangeSet<A> {
670    fn from(value: bool) -> Self {
671        if value {
672            Self::all()
673        } else {
674            Self::empty()
675        }
676    }
677}
678
679impl<T: RangeSetEntry, A: Array<Item = T>> RangeSet<A> {
680    fn from_range(a: Range<T>) -> Self {
681        if a.start < a.end {
682            let mut t = SmallVec::new();
683            t.push(a.start);
684            t.push(a.end);
685            Self::new_unchecked_impl(t)
686        } else {
687            Self::empty()
688        }
689    }
690}
691
692impl<T: RangeSetEntry, A: Array<Item = T>> From<Range<T>> for RangeSet<A> {
693    fn from(value: Range<T>) -> Self {
694        Self::from_range(value)
695    }
696}
697
698impl<T: RangeSetEntry, A: Array<Item = T>> From<RangeFrom<T>> for RangeSet<A> {
699    fn from(value: RangeFrom<T>) -> Self {
700        Self::from_range_from(value.start)
701    }
702}
703
704impl<T: RangeSetEntry, A: Array<Item = T>> From<RangeTo<T>> for RangeSet<A> {
705    fn from(value: RangeTo<T>) -> Self {
706        Self::from_range_until(value.end)
707    }
708}
709
710impl<T: RangeSetEntry, A: Array<Item = T>> From<RangeFull> for RangeSet<A> {
711    fn from(_: RangeFull) -> Self {
712        Self::all()
713    }
714}
715
716/// compute the intersection of this range set with another, producing a new range set
717///
718/// &forall; t &isin; T, r(t) = a(t) & b(t)
719impl<T: RangeSetEntry + Clone, A: Array<Item = T>> BitAnd<RangeSet<A>> for RangeSet<A> {
720    type Output = RangeSet<A>;
721    fn bitand(self, that: RangeSet<A>) -> Self::Output {
722        self.intersection(&that)
723    }
724}
725
726impl<T: RangeSetEntry + Clone, A: Array<Item = T>> BitAnd<&RangeSet<A>> for RangeSet<A> {
727    type Output = RangeSet<A>;
728    fn bitand(self, that: &RangeSet<A>) -> Self::Output {
729        self.intersection(that)
730    }
731}
732
733impl<T: RangeSetEntry + Clone, A: Array<Item = T>> BitAnd<RangeSet<A>> for &RangeSet<A> {
734    type Output = RangeSet<A>;
735    fn bitand(self, that: RangeSet<A>) -> Self::Output {
736        self.intersection(&that)
737    }
738}
739
740impl<T: RangeSetEntry + Clone, A: Array<Item = T>> BitAnd<&RangeSet<A>> for &RangeSet<A> {
741    type Output = RangeSet<A>;
742    fn bitand(self, that: &RangeSet<A>) -> Self::Output {
743        self.intersection(that)
744    }
745}
746
747impl<T: Ord, A: Array<Item = T>> BitAndAssign for RangeSet<A> {
748    fn bitand_assign(&mut self, that: Self) {
749        InPlaceMergeState::merge(&mut self.0, that.0, IntersectionOp::<{ usize::MAX }>);
750    }
751}
752
753/// compute the union of this range set with another, producing a new range set
754///
755/// &forall; t &isin; T, r(t) = a(t) | b(t)
756impl<T: RangeSetEntry + Clone, A: Array<Item = T>> BitOr<RangeSet<A>> for RangeSet<A> {
757    type Output = RangeSet<A>;
758    fn bitor(self, that: RangeSet<A>) -> Self::Output {
759        self.union(&that)
760    }
761}
762
763impl<T: RangeSetEntry + Clone, A: Array<Item = T>> BitOr<&RangeSet<A>> for RangeSet<A> {
764    type Output = RangeSet<A>;
765    fn bitor(self, that: &RangeSet<A>) -> Self::Output {
766        self.union(that)
767    }
768}
769
770impl<T: RangeSetEntry + Clone, A: Array<Item = T>> BitOr<RangeSet<A>> for &RangeSet<A> {
771    type Output = RangeSet<A>;
772    fn bitor(self, that: RangeSet<A>) -> Self::Output {
773        self.union(&that)
774    }
775}
776
777impl<T: RangeSetEntry + Clone, A: Array<Item = T>> BitOr<&RangeSet<A>> for &RangeSet<A> {
778    type Output = RangeSet<A>;
779    fn bitor(self, that: &RangeSet<A>) -> Self::Output {
780        self.union(that)
781    }
782}
783
784impl<T: Ord, A: Array<Item = T>> BitOrAssign for RangeSet<A> {
785    fn bitor_assign(&mut self, that: Self) {
786        InPlaceMergeState::merge(&mut self.0, that.0, UnionOp);
787    }
788}
789
790/// compute the exclusive or of this range set with another, producing a new range set
791///
792/// &forall; t &isin; T, r(t) = a(t) ^ b(t)
793impl<T: RangeSetEntry + Clone, A: Array<Item = T>> BitXor<RangeSet<A>> for RangeSet<A> {
794    type Output = RangeSet<A>;
795    fn bitxor(self, that: RangeSet<A>) -> Self::Output {
796        self.symmetric_difference(&that)
797    }
798}
799
800impl<T: RangeSetEntry + Clone, A: Array<Item = T>> BitXor<&RangeSet<A>> for RangeSet<A> {
801    type Output = RangeSet<A>;
802    fn bitxor(self, that: &RangeSet<A>) -> Self::Output {
803        self.symmetric_difference(that)
804    }
805}
806
807impl<T: RangeSetEntry + Clone, A: Array<Item = T>> BitXor<RangeSet<A>> for &RangeSet<A> {
808    type Output = RangeSet<A>;
809    fn bitxor(self, that: RangeSet<A>) -> Self::Output {
810        self.symmetric_difference(&that)
811    }
812}
813
814impl<T: RangeSetEntry + Clone, A: Array<Item = T>> BitXor<&RangeSet<A>> for &RangeSet<A> {
815    type Output = RangeSet<A>;
816    fn bitxor(self, that: &RangeSet<A>) -> Self::Output {
817        self.symmetric_difference(that)
818    }
819}
820
821impl<T: RangeSetEntry, A: Array<Item = T>> BitXorAssign for RangeSet<A> {
822    fn bitxor_assign(&mut self, that: Self) {
823        InPlaceMergeState::merge(&mut self.0, that.0, XorOp);
824    }
825}
826
827/// compute the difference of this range set with another, producing a new range set
828///
829/// &forall; t &isin; T, r(t) = a(t) & !b(t)
830impl<T: RangeSetEntry + Clone, A: Array<Item = T>> Sub<RangeSet<A>> for RangeSet<A> {
831    type Output = RangeSet<A>;
832    fn sub(self, that: RangeSet<A>) -> Self::Output {
833        self.difference(&that)
834    }
835}
836
837impl<T: RangeSetEntry + Clone, A: Array<Item = T>> Sub<&RangeSet<A>> for RangeSet<A> {
838    type Output = RangeSet<A>;
839    fn sub(self, that: &RangeSet<A>) -> Self::Output {
840        self.difference(that)
841    }
842}
843
844impl<T: RangeSetEntry + Clone, A: Array<Item = T>> Sub<RangeSet<A>> for &RangeSet<A> {
845    type Output = RangeSet<A>;
846    fn sub(self, that: RangeSet<A>) -> Self::Output {
847        self.difference(&that)
848    }
849}
850
851impl<T: RangeSetEntry + Clone, A: Array<Item = T>> Sub<&RangeSet<A>> for &RangeSet<A> {
852    type Output = RangeSet<A>;
853    fn sub(self, that: &RangeSet<A>) -> Self::Output {
854        self.difference(that)
855    }
856}
857
858impl<T: Ord, A: Array<Item = T>> SubAssign for RangeSet<A> {
859    fn sub_assign(&mut self, that: Self) {
860        InPlaceMergeState::merge(&mut self.0, that.0, DiffOp::<{ usize::MAX }>);
861    }
862}
863
864/// compute the negation of this range set
865///
866/// &forall; t &isin; T, r(t) = !a(t)
867impl<T: RangeSetEntry + Clone, A: Array<Item = T>> Not for RangeSet<A> {
868    type Output = RangeSet<A>;
869    fn not(mut self) -> Self::Output {
870        match self.0.first() {
871            Some(x) if x.is_min_value() => {
872                self.0.remove(0);
873            }
874            _ => {
875                self.0.insert(0, T::min_value());
876            }
877        }
878        self
879    }
880}
881
882/// compute the negation of this range set
883///
884/// &forall; t &isin; T, r(t) = !a(t)
885impl<T: RangeSetEntry + Clone, A: Array<Item = T>> Not for &RangeSet<A> {
886    type Output = RangeSet<A>;
887    fn not(self) -> Self::Output {
888        self ^ &RangeSet::all()
889    }
890}
891
892struct RangeSetBoolOpMergeState<'a, T> {
893    inner: BoolOpMergeState<'a, T, T>,
894}
895
896impl<'a, T> RangeSetBoolOpMergeState<'a, T> {
897    fn merge<O: MergeOperation<Self>>(a: &'a [T], b: &'a [T], o: O) -> bool {
898        let mut state = Self {
899            inner: BoolOpMergeState::new(a, b),
900        };
901        o.merge(&mut state);
902        state.inner.result()
903    }
904}
905
906impl<'a, T> MergeStateMut for RangeSetBoolOpMergeState<'a, T> {
907    fn advance_a(&mut self, n: usize, copy: bool) -> bool {
908        self.inner.advance_a(n, copy)
909    }
910    fn advance_b(&mut self, n: usize, copy: bool) -> bool {
911        self.inner.advance_b(n, copy)
912    }
913    fn ac(&self) -> bool {
914        self.inner.ac()
915    }
916    fn bc(&self) -> bool {
917        self.inner.bc()
918    }
919}
920
921impl<'a, T> MergeState for RangeSetBoolOpMergeState<'a, T> {
922    type A = T;
923    type B = T;
924    fn a_slice(&self) -> &[T] {
925        self.inner.a_slice()
926    }
927    fn b_slice(&self) -> &[T] {
928        self.inner.b_slice()
929    }
930}
931
932struct VecMergeState<'a, T, A: Array> {
933    inner: SmallVecMergeState<'a, T, T, A>,
934}
935
936impl<'a, T: Clone, A: Array<Item = T>> VecMergeState<'a, T, A> {
937    fn merge<O: MergeOperation<Self>>(a: &'a [T], b: &'a [T], o: O) -> SmallVec<A> {
938        let mut state = Self {
939            inner: SmallVecMergeState::new(a, b, SmallVec::new()),
940        };
941        o.merge(&mut state);
942        state.inner.result()
943    }
944}
945
946impl<'a, T: Clone, A: Array<Item = T>> MergeStateMut for VecMergeState<'a, T, A> {
947    fn advance_a(&mut self, n: usize, copy: bool) -> bool {
948        self.inner.advance_a(n, copy)
949    }
950    fn advance_b(&mut self, n: usize, copy: bool) -> bool {
951        self.inner.advance_b(n, copy)
952    }
953
954    fn ac(&self) -> bool {
955        self.inner.ac()
956    }
957
958    fn bc(&self) -> bool {
959        self.inner.bc()
960    }
961}
962
963impl<'a, T, A: Array<Item = T>> MergeState for VecMergeState<'a, T, A> {
964    type A = T;
965    type B = T;
966    fn a_slice(&self) -> &[T] {
967        self.inner.a_slice()
968    }
969    fn b_slice(&self) -> &[T] {
970        self.inner.b_slice()
971    }
972}
973
974#[cfg(feature = "serde")]
975impl<T: Serialize, A: Array<Item = T>> Serialize for RangeSet<A> {
976    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
977        let mut map = serializer.serialize_seq(Some(self.0.len()))?;
978        for x in self.0.iter() {
979            map.serialize_element(x)?;
980        }
981        map.end()
982    }
983}
984
985#[cfg(feature = "serde")]
986impl<'de, T: Deserialize<'de> + Ord, A: Array<Item = T>> Deserialize<'de> for RangeSet<A> {
987    fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
988        deserializer.deserialize_seq(RangeSetVisitor {
989            phantom: PhantomData,
990        })
991    }
992}
993
994#[cfg(feature = "serde")]
995struct RangeSetVisitor<T, A> {
996    phantom: PhantomData<(T, A)>,
997}
998
999#[cfg(feature = "serde")]
1000impl<'de, T, A: Array<Item = T>> Visitor<'de> for RangeSetVisitor<T, A>
1001where
1002    T: Deserialize<'de> + Ord,
1003{
1004    type Value = RangeSet<A>;
1005
1006    fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
1007        formatter.write_str("a sequence")
1008    }
1009
1010    fn visit_seq<B>(self, mut seq: B) -> Result<Self::Value, B::Error>
1011    where
1012        B: SeqAccess<'de>,
1013    {
1014        let len = seq.size_hint().unwrap_or(0);
1015        let mut boundaries: SmallVec<A> = SmallVec::with_capacity(len);
1016        while let Some(value) = seq.next_element::<A::Item>()? {
1017            boundaries.push(value);
1018        }
1019        boundaries.sort();
1020        boundaries.dedup();
1021        Ok(RangeSet(boundaries))
1022    }
1023}
1024
1025#[cfg(feature = "rkyv")]
1026impl<T, A> rkyv::Archive for RangeSet<A>
1027where
1028    T: rkyv::Archive,
1029    A: Array<Item = T>,
1030{
1031    type Archived = ArchivedRangeSet<<T as rkyv::Archive>::Archived>;
1032
1033    type Resolver = rkyv::vec::VecResolver;
1034
1035    unsafe fn resolve(&self, pos: usize, resolver: Self::Resolver, out: *mut Self::Archived) {
1036        rkyv::vec::ArchivedVec::resolve_from_slice(
1037            self.0.as_slice(),
1038            pos,
1039            resolver,
1040            &mut (*out).0 as *mut rkyv::vec::ArchivedVec<<T as rkyv::Archive>::Archived>,
1041        );
1042    }
1043}
1044
1045#[cfg(feature = "rkyv")]
1046impl<T, S, A> rkyv::Serialize<S> for RangeSet<A>
1047where
1048    T: rkyv::Archive + rkyv::Serialize<S>,
1049    S: rkyv::ser::ScratchSpace + rkyv::ser::Serializer,
1050    A: Array<Item = T>,
1051{
1052    fn serialize(&self, serializer: &mut S) -> Result<Self::Resolver, S::Error> {
1053        rkyv::vec::ArchivedVec::serialize_from_slice(self.0.as_ref(), serializer)
1054    }
1055}
1056
1057#[cfg(feature = "rkyv")]
1058impl<T, A, D> rkyv::Deserialize<RangeSet<A>, D> for ArchivedRangeSet<T::Archived>
1059where
1060    T: rkyv::Archive,
1061    A: Array<Item = T>,
1062    D: rkyv::Fallible + ?Sized,
1063    [T::Archived]: rkyv::DeserializeUnsized<[T], D>,
1064{
1065    fn deserialize(&self, deserializer: &mut D) -> Result<RangeSet<A>, D::Error> {
1066        // todo: replace this with SmallVec once smallvec support for rkyv lands on crates.io
1067        let boundaries: Vec<T> = self.0.deserialize(deserializer)?;
1068        Ok(RangeSet(boundaries.into()))
1069    }
1070}
1071
1072/// Archived version of a RangeSet
1073#[cfg(feature = "rkyv")]
1074#[repr(transparent)]
1075pub struct ArchivedRangeSet<T>(rkyv::vec::ArchivedVec<T>);
1076
1077#[cfg(feature = "rkyv")]
1078impl<T: Debug> Debug for ArchivedRangeSet<T> {
1079    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1080        write!(f, "ArchivedRangeSet{{")?;
1081        for (i, r) in self.iter().enumerate() {
1082            if i > 0 {
1083                write!(f, ", ")?;
1084            }
1085            write!(f, "{r:?}")?;
1086        }
1087        write!(f, "}}")
1088    }
1089}
1090
1091/// Validation error for a range set
1092#[cfg(feature = "rkyv_validated")]
1093#[derive(Debug)]
1094pub enum ArchivedRangeSetError {
1095    /// error with the individual fields of the ArchivedRangeSet, e.g a NonZeroU64 with a value of 0
1096    ValueCheckError,
1097    /// boundaries were not properly ordered
1098    OrderCheckError,
1099}
1100
1101#[cfg(feature = "rkyv_validated")]
1102impl std::error::Error for ArchivedRangeSetError {}
1103
1104#[cfg(feature = "rkyv_validated")]
1105impl std::fmt::Display for ArchivedRangeSetError {
1106    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1107        write!(f, "{:?}", self)
1108    }
1109}
1110
1111#[cfg(feature = "rkyv_validated")]
1112impl<C: ?Sized, T> bytecheck::CheckBytes<C> for ArchivedRangeSet<T>
1113where
1114    T: Ord,
1115    bool: bytecheck::CheckBytes<C>,
1116    rkyv::vec::ArchivedVec<T>: bytecheck::CheckBytes<C>,
1117{
1118    type Error = ArchivedRangeSetError;
1119    unsafe fn check_bytes<'a>(
1120        value: *const Self,
1121        context: &mut C,
1122    ) -> Result<&'a Self, Self::Error> {
1123        let boundaries = &(*value).0;
1124        rkyv::vec::ArchivedVec::<T>::check_bytes(boundaries, context)
1125            .map_err(|_| ArchivedRangeSetError::ValueCheckError)?;
1126        if !boundaries
1127            .iter()
1128            .zip(boundaries.iter().skip(1))
1129            .all(|(a, b)| a < b)
1130        {
1131            return Err(ArchivedRangeSetError::OrderCheckError);
1132        };
1133        Ok(&*value)
1134    }
1135}
1136
1137struct UnionOp;
1138struct XorOp;
1139struct IntersectionOp<const T: usize>;
1140struct DiffOp<const T: usize>;
1141
1142impl<T: Ord, M: MergeStateMut<A = T, B = T>> MergeOperation<M> for UnionOp {
1143    fn from_a(&self, m: &mut M, n: usize) -> bool {
1144        m.advance_a(n, !m.bc())
1145    }
1146    fn from_b(&self, m: &mut M, n: usize) -> bool {
1147        m.advance_b(n, !m.ac())
1148    }
1149    fn collision(&self, m: &mut M) -> bool {
1150        m.advance_both(m.ac() == m.bc())
1151    }
1152    fn cmp(&self, a: &T, b: &T) -> Ordering {
1153        a.cmp(b)
1154    }
1155}
1156
1157impl<T: Ord, M: MergeStateMut<A = T, B = T>, const X: usize> MergeOperation<M>
1158    for IntersectionOp<X>
1159{
1160    fn from_a(&self, m: &mut M, n: usize) -> bool {
1161        m.advance_a(n, m.bc())
1162    }
1163    fn from_b(&self, m: &mut M, n: usize) -> bool {
1164        m.advance_b(n, m.ac())
1165    }
1166    fn collision(&self, m: &mut M) -> bool {
1167        m.advance_both(m.ac() == m.bc())
1168    }
1169    fn cmp(&self, a: &T, b: &T) -> Ordering {
1170        a.cmp(b)
1171    }
1172    const MCM_THRESHOLD: usize = X;
1173}
1174
1175impl<T: Ord, M: MergeStateMut<A = T, B = T>, const X: usize> MergeOperation<M> for DiffOp<X> {
1176    fn from_a(&self, m: &mut M, n: usize) -> bool {
1177        m.advance_a(n, !m.bc())
1178    }
1179    fn from_b(&self, m: &mut M, n: usize) -> bool {
1180        m.advance_b(n, m.ac())
1181    }
1182    fn collision(&self, m: &mut M) -> bool {
1183        m.advance_both(m.ac() != m.bc())
1184    }
1185    fn cmp(&self, a: &T, b: &T) -> Ordering {
1186        a.cmp(b)
1187    }
1188    const MCM_THRESHOLD: usize = X;
1189}
1190
1191impl<T: Ord, M: MergeStateMut<A = T, B = T>> MergeOperation<M> for XorOp {
1192    fn from_a(&self, m: &mut M, n: usize) -> bool {
1193        m.advance_a(n, true)
1194    }
1195    fn from_b(&self, m: &mut M, n: usize) -> bool {
1196        m.advance_b(n, true)
1197    }
1198    fn collision(&self, m: &mut M) -> bool {
1199        m.advance_both(false)
1200    }
1201    fn cmp(&self, a: &T, b: &T) -> Ordering {
1202        a.cmp(b)
1203    }
1204}
1205
1206#[inline]
1207fn is_odd(x: usize) -> bool {
1208    (x & 1) != 0
1209}
1210
1211#[inline]
1212fn is_even(x: usize) -> bool {
1213    (x & 1) == 0
1214}
1215
1216fn is_strictly_sorted<T: Ord>(ranges: &[T]) -> bool {
1217    for i in 0..ranges.len().saturating_sub(1) {
1218        if ranges[i] >= ranges[i + 1] {
1219            return false;
1220        }
1221    }
1222    true
1223}
1224
1225/// Split a strictly ordered sequence of boundaries `ranges` into two parts
1226/// `left`, `right` at position `at`, so that
1227///   contains(left, x) == contains(ranges, x) for x < at
1228///   contains(right, x) == contains(ranges, x) for x >= at
1229///
1230/// The returned slices are guaranteed to be minimal. The left slice will contain
1231/// no boundaries after the split point, and the right slice will contain at most
1232/// one boundary before the split point.
1233#[inline]
1234fn split<T: Ord>(ranges: &[T], at: T) -> (&[T], &[T]) {
1235    let l = ranges.len();
1236    let res = ranges.binary_search(&at);
1237    match res {
1238        Ok(i) if is_even(i) => {
1239            // left will be an even size, so we can just cut it off
1240            (&ranges[..i], &ranges[i..])
1241        }
1242        Err(i) if is_even(i) => {
1243            // right will be an even size, so we can just cut it off
1244            (&ranges[..i], &ranges[i..])
1245        }
1246        Ok(i) => {
1247            // left will be an odd size, so we need to add one if possible
1248            //
1249            // since i is an odd value, it indicates going to false at the
1250            // split point, and we don't need to have it in right.
1251            let sp = i.saturating_add(1).min(l);
1252            (&ranges[..i], &ranges[sp..])
1253        }
1254        Err(i) => {
1255            // left will be an odd size, so we add one if possible
1256            //
1257            // i is an odd value, so right is true at the split point, and
1258            // we need to add one value before the split point to right.
1259            // hence the saturating_sub(1).
1260            (&ranges[..i], &ranges[i.saturating_sub(1)..])
1261        }
1262    }
1263}
1264
1265/// For a strictly ordered sequence of boundaries `ranges`, checks if the
1266/// value at `at` is true.
1267#[allow(dead_code)]
1268fn contains<T: Ord>(boundaries: &[T], value: &T) -> bool {
1269    match boundaries.binary_search(value) {
1270        Ok(index) => !is_odd(index),
1271        Err(index) => is_odd(index),
1272    }
1273}
1274
1275/// Check if a sequence of boundaries `ranges` intersects with a range
1276#[allow(dead_code)]
1277fn intersects<T: Ord>(boundaries: &[T], range: Range<T>) -> bool {
1278    let (_, remaining) = split(boundaries, range.start);
1279    let (remaining, _) = split(remaining, range.end);
1280    // remaining is not the intersection but can be larger.
1281    // But if remaining is empty, then we know that the intersection is empty.
1282    !remaining.is_empty()
1283}
1284
1285#[cfg(test)]
1286mod util_tests {
1287    use std::{collections::BTreeSet, ops::Range};
1288
1289    use super::*;
1290    use proptest::prelude::*;
1291
1292    fn test_points(boundaries: impl IntoIterator<Item = u64>) -> BTreeSet<u64> {
1293        let mut res = BTreeSet::new();
1294        for x in boundaries {
1295            res.insert(x.saturating_sub(1));
1296            res.insert(x);
1297            res.insert(x.saturating_add(1));
1298        }
1299        res
1300    }
1301
1302    fn test_boundaries() -> impl Strategy<Value = (Vec<u64>, u64)> {
1303        proptest::collection::vec(any::<u64>(), 0..100).prop_flat_map(|mut v| {
1304            v.sort();
1305            v.dedup();
1306            // split point should occasionally be outside of the range
1307            let max_split = v
1308                .iter()
1309                .max()
1310                .cloned()
1311                .unwrap_or_default()
1312                .saturating_add(2);
1313            (Just(v), 0..max_split)
1314        })
1315    }
1316
1317    proptest! {
1318        #[test]
1319        fn test_split((boundaries, at) in test_boundaries()) {
1320            let (left, right) = split(&boundaries, at);
1321            for x in test_points(boundaries.clone()) {
1322                // test that split does what it promises
1323                if x < at {
1324                    prop_assert_eq!(contains(left, &x), contains(&boundaries, &x), "left must be like boundaries for x < at");
1325                } else {
1326                    prop_assert_eq!(contains(right, &x), contains(&boundaries, &x), "right must be like boundaries for x >= at");
1327                }
1328                // test that split is not just returning the input, but minimal parts
1329                let nr = right.iter().filter(|x| x < &&at).count();
1330                prop_assert!(nr <= 1, "there must be at most one boundary before the split point");
1331                let nl = left.iter().filter(|x| x >= &&at).count();
1332                prop_assert!(nl == 0, "there must be no boundaries after the split point");
1333            }
1334        }
1335    }
1336
1337    #[test]
1338    fn test_split_0() {
1339        #[allow(clippy::type_complexity)]
1340        let cases: Vec<(&[u64], u64, (&[u64], &[u64]))> = vec![
1341            (&[0, 2], 0, (&[], &[0, 2])),
1342            (&[0, 2], 2, (&[0], &[])),
1343            (&[0, 2, 4], 2, (&[0], &[4])),
1344            (&[0, 2, 4], 4, (&[0, 2], &[4])),
1345            (&[0, 2, 4, 8], 2, (&[0], &[4, 8])),
1346            (&[0, 2, 4, 8], 4, (&[0, 2], &[4, 8])),
1347            (&[0, 2, 4, 8], 3, (&[0, 2], &[4, 8])),
1348            (&[0, 2, 4, 8], 6, (&[0, 2, 4], &[4, 8])),
1349        ];
1350        for (ranges, pos, (left, right)) in cases {
1351            assert_eq!(split(ranges, pos), (left, right));
1352        }
1353    }
1354
1355    #[test]
1356    fn test_intersects_0() {
1357        let cases: Vec<(&[u64], Range<u64>, bool)> = vec![
1358            (&[0, 2], 0..2, true),
1359            (&[0, 2], 2..4, false),
1360            (&[0, 2, 4, 8], 0..2, true),
1361            (&[0, 2, 4, 8], 2..4, false),
1362            (&[0, 2, 4, 8], 4..8, true),
1363            (&[0, 2, 4, 8], 8..12, false),
1364        ];
1365        for (ranges, range, expected) in cases {
1366            assert_eq!(intersects(ranges, range), expected);
1367        }
1368    }
1369
1370    #[test]
1371    fn contains_0() {
1372        let cases: Vec<(&[u64], u64, bool)> = vec![
1373            (&[0, 2], 0, true),
1374            (&[0, 2], 1, true),
1375            (&[0, 2], 2, false),
1376            (&[0, 2, 4, 8], 3, false),
1377            (&[0, 2, 4, 8], 4, true),
1378        ];
1379        for (ranges, pos, expected) in cases {
1380            assert_eq!(contains(ranges, &pos), expected);
1381        }
1382    }
1383}
1384
1385#[cfg(test)]
1386mod tests {
1387    use super::*;
1388    use num_traits::{Bounded, PrimInt};
1389    use obey::*;
1390    use quickcheck::*;
1391    use std::collections::BTreeSet;
1392    use std::ops::RangeBounds;
1393
1394    impl<T: RangeSetEntry + Clone, A: Array<Item = T>> RangeSet<A> {
1395        fn from_range_bounds<R: RangeBounds<T>>(r: R) -> std::result::Result<Self, ()> {
1396            match (r.start_bound(), r.end_bound()) {
1397                (Bound::Unbounded, Bound::Unbounded) => Ok(Self::all()),
1398                (Bound::Unbounded, Bound::Excluded(b)) => Ok(Self::from_range_until(b.clone())),
1399                (Bound::Included(a), Bound::Unbounded) => Ok(Self::from_range_from(a.clone())),
1400                (Bound::Included(a), Bound::Excluded(b)) => Ok(Self::from_range(Range {
1401                    start: a.clone(),
1402                    end: b.clone(),
1403                })),
1404                _ => Err(()),
1405            }
1406        }
1407    }
1408
1409    impl<T: Arbitrary + Ord, A: Array<Item = T> + Clone + 'static> Arbitrary for RangeSet<A> {
1410        fn arbitrary<G: Gen>(g: &mut G) -> Self {
1411            let mut boundaries: Vec<T> = Arbitrary::arbitrary(g);
1412            boundaries.truncate(4);
1413            boundaries.sort();
1414            boundaries.dedup();
1415            Self::new_unchecked_impl(boundaries.into())
1416        }
1417    }
1418
1419    /// A range set can be seen as a set of elements, even though it does not actually contain the elements
1420    impl<E: PrimInt + RangeSetEntry + Clone, A: Array<Item = E>> TestSamples<E, bool> for RangeSet<A> {
1421        fn samples(&self, res: &mut BTreeSet<E>) {
1422            res.insert(<E as Bounded>::min_value());
1423            for x in self.0.iter().cloned() {
1424                res.insert(x.saturating_sub(E::one()));
1425                res.insert(x);
1426                res.insert(x.saturating_add(E::one()));
1427            }
1428            res.insert(E::max_value());
1429        }
1430
1431        fn at(&self, elem: E) -> bool {
1432            self.contains(&elem)
1433        }
1434    }
1435    type Test = RangeSet<[i64; 4]>;
1436
1437    #[test]
1438    fn smoke_test() {
1439        let x: Test = Test::from(0..10);
1440        println!(
1441            "{:?} {:?} {:?} {:?} {:?}",
1442            x,
1443            x.contains(&0),
1444            x.contains(&1),
1445            x.contains(&9),
1446            x.contains(&10)
1447        );
1448
1449        let y: Test = Test::from(..10);
1450        let z: Test = Test::from(20..);
1451
1452        let r: Test = (&x).bitor(&z);
1453
1454        println!("{:?} {:?} {:?} {:?}", x, y, z, r);
1455
1456        let r2: Test = &x & &y;
1457        let r3: Test = &x | &y;
1458        let r4 = y.is_disjoint(&z);
1459        let r5 = (&y).bitand(&z);
1460
1461        println!("{:?}", r2);
1462        println!("{:?}", r3);
1463        println!("{:?} {:?}", r4, r5);
1464    }
1465
1466    #[cfg(feature = "serde")]
1467    #[quickcheck]
1468    fn range_seq_serde(a: Test) -> bool {
1469        let bytes = serde_cbor::to_vec(&a).unwrap();
1470        let b: Test = serde_cbor::from_slice(&bytes).unwrap();
1471        a == b
1472    }
1473
1474    #[cfg(feature = "rkyv")]
1475    #[quickcheck]
1476    fn range_seq_rkyv_unvalidated(a: Test) -> bool {
1477        use rkyv::*;
1478        use ser::Serializer;
1479        let mut serializer = ser::serializers::AllocSerializer::<256>::default();
1480        serializer.serialize_value(&a).unwrap();
1481        let bytes = serializer.into_serializer().into_inner();
1482        let archived = unsafe { rkyv::archived_root::<Test>(&bytes) };
1483        let deserialized: Test = archived.deserialize(&mut Infallible).unwrap();
1484        a == deserialized
1485    }
1486
1487    #[cfg(feature = "rkyv_validated")]
1488    #[quickcheck]
1489    fn range_seq_rkyv_validated(a: Test) -> bool {
1490        use rkyv::*;
1491        use ser::Serializer;
1492        let mut serializer = ser::serializers::AllocSerializer::<256>::default();
1493        serializer.serialize_value(&a).unwrap();
1494        let bytes = serializer.into_serializer().into_inner();
1495        let archived = rkyv::check_archived_root::<Test>(&bytes).unwrap();
1496        let deserialized: Test = archived.deserialize(&mut Infallible).unwrap();
1497        a == deserialized
1498    }
1499
1500    #[cfg(feature = "rkyv_validated")]
1501    #[test]
1502    fn range_seq_rkyv_errors() {
1503        use rkyv::*;
1504        use std::num::NonZeroU64;
1505
1506        // deserialize a boolean value of 2, must produce an error!
1507        let mut bytes = AlignedVec::new();
1508        bytes.extend_from_slice(&hex::decode("000000000000000002000000").unwrap());
1509        assert!(rkyv::check_archived_root::<Test>(&bytes).is_err());
1510
1511        // deserialize wrongly ordered range set, must produce an error
1512        let mut bytes = AlignedVec::new();
1513        bytes.extend_from_slice(
1514            &hex::decode("02000000000000000100000000000000f0ffffff0200000000000000").unwrap(),
1515        );
1516        assert!(rkyv::check_archived_root::<Test>(&bytes).is_err());
1517
1518        // deserialize wrong value (0 for a NonZeroU64), must produce an error
1519        let mut bytes = AlignedVec::new();
1520        bytes.extend_from_slice(
1521            &hex::decode("00000000000000000100000000000000f0ffffff0200000000000000").unwrap(),
1522        );
1523        assert!(rkyv::check_archived_root::<RangeSet2<NonZeroU64>>(&bytes).is_err());
1524    }
1525
1526    #[quickcheck]
1527    fn ranges_consistent(a: Test) -> bool {
1528        let mut b = Test::empty();
1529        for e in a.iter() {
1530            let e = e.cloned();
1531            b |= Test::from_range_bounds(e).unwrap();
1532        }
1533        a == b
1534    }
1535
1536    #[quickcheck]
1537    fn is_disjoint_sample(a: Test, b: Test) -> bool {
1538        let res = binary_property_test(&a, &b, a.is_disjoint(&b), |a, b| !(a & b));
1539        if !res {
1540            println!("{:?} {:?} {:?}", a, b, a.is_disjoint(&b));
1541        }
1542        res
1543    }
1544
1545    #[quickcheck]
1546    fn is_subset_sample(a: Test, b: Test) -> bool {
1547        binary_property_test(&a, &b, a.is_subset(&b), |a, b| !a | b)
1548    }
1549
1550    #[quickcheck]
1551    fn negation_check(a: RangeSet2<i64>) -> bool {
1552        unary_element_test(&a, !a.clone(), |x| !x)
1553    }
1554
1555    #[quickcheck]
1556    fn union_check(a: RangeSet2<i64>, b: RangeSet2<i64>) -> bool {
1557        binary_element_test(&a, &b, &a | &b, |a, b| a | b)
1558    }
1559
1560    #[quickcheck]
1561    fn intersection_check(a: RangeSet2<i64>, b: RangeSet2<i64>) -> bool {
1562        binary_element_test(&a, &b, &a & &b, |a, b| a & b)
1563    }
1564
1565    #[quickcheck]
1566    fn xor_check(a: RangeSet2<i64>, b: RangeSet2<i64>) -> bool {
1567        binary_element_test(&a, &b, &a ^ &b, |a, b| a ^ b)
1568    }
1569
1570    #[quickcheck]
1571    fn difference_check(a: RangeSet2<i64>, b: RangeSet2<i64>) -> bool {
1572        binary_element_test(&a, &b, &a - &b, |a, b| a & !b)
1573    }
1574
1575    bitop_assign_consistent!(Test);
1576    bitop_symmetry!(Test);
1577    bitop_empty!(Test);
1578    bitop_sub_not_all!(Test);
1579    set_predicate_consistent!(Test);
1580}