rangeset/
ops.rs

1//! Set operations.
2
3#[cfg(feature = "alloc")]
4mod cover;
5
6#[cfg(feature = "alloc")]
7pub use cover::Cover;
8
9use core::marker::PhantomData;
10
11use crate::iter::{IntoRangeIterator, RangeIterator};
12
13/// Set operations.
14pub trait Set<Rhs> {
15    /// Union type.
16    type Union<'a>
17    where
18        Self: 'a,
19        Rhs: 'a;
20
21    /// Difference type.
22    type Difference<'a>
23    where
24        Self: 'a,
25        Rhs: 'a;
26
27    /// Intersection type.
28    type Intersection<'a>
29    where
30        Self: 'a,
31        Rhs: 'a;
32
33    /// Symmetric difference type.
34    type SymmetricDifference<'a>
35    where
36        Self: 'a,
37        Rhs: 'a;
38
39    /// Returns the set union of `self` and `rhs`.
40    fn union<'a>(&'a self, rhs: Rhs) -> Self::Union<'a>
41    where
42        Rhs: 'a;
43
44    /// Returns the set difference of `self` and `rhs`.
45    fn difference<'a>(&'a self, rhs: Rhs) -> Self::Difference<'a>
46    where
47        Rhs: 'a;
48
49    /// Returns the set intersection of `self` and `rhs`.
50    fn intersection<'a>(&'a self, rhs: Rhs) -> Self::Intersection<'a>
51    where
52        Rhs: 'a;
53
54    /// Returns the set symmetric difference of `self` and `rhs`.
55    fn symmetric_difference<'a>(&'a self, rhs: Rhs) -> Self::SymmetricDifference<'a>
56    where
57        Rhs: 'a;
58
59    /// Returns `true` if `self` is disjoint with `other`.
60    fn is_disjoint(&self, other: Rhs) -> bool;
61
62    /// Returns `true` if `self` is a subset of `other`.
63    fn is_subset(&self, other: Rhs) -> bool;
64
65    /// Returns `true` if `self` is a superset of `other`.
66    fn is_superset(&self, other: Rhs) -> bool;
67}
68
69/// Indexing operation.
70pub trait Index<Idx> {
71    /// Output type.
72    type Output<'a>
73    where
74        Self: 'a,
75        Idx: 'a;
76
77    /// Index the collection by the given index.
78    fn index<'a>(&'a self, index: Idx) -> Self::Output<'a>
79    where
80        Idx: 'a;
81}
82
83/// Iterator over a slice using an index.
84#[derive(Debug)]
85#[must_use = "iterators are lazy and do nothing unless consumed"]
86pub struct SliceIndexIter<'a, T, I> {
87    slice: &'a [T],
88    iter: I,
89    _pd: PhantomData<&'a T>,
90}
91
92impl<'a, T, I> Iterator for SliceIndexIter<'a, T, I>
93where
94    I: RangeIterator<usize>,
95{
96    type Item = &'a [T];
97
98    fn next(&mut self) -> Option<Self::Item> {
99        self.iter.next().map(|range| &self.slice[range])
100    }
101}
102
103impl<T, Idx> Index<Idx> for [T]
104where
105    Idx: IntoRangeIterator<usize>,
106{
107    type Output<'a>
108        = SliceIndexIter<'a, T, Idx::IntoIter>
109    where
110        T: 'a,
111        Idx: 'a;
112
113    fn index<'a>(&'a self, index: Idx) -> Self::Output<'a>
114    where
115        Idx: 'a,
116    {
117        SliceIndexIter {
118            slice: self,
119            iter: index.into_range_iter(),
120            _pd: PhantomData,
121        }
122    }
123}