1#![deny(missing_docs)]
2extern crate enum_like;
13extern crate bit_set;
14
15use enum_like::EnumLike;
16use bit_set::BitSet;
17use std::marker::PhantomData;
18use std::iter::FromIterator;
19use std::fmt;
20
21#[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
23pub struct EnumSet<E: EnumLike> {
24 inner: BitSet,
25 _phantom: PhantomData<E>,
26}
27
28impl<E: EnumLike> EnumSet<E> {
29 pub fn into_bit_set(self) -> BitSet {
31 self.inner
32 }
33
34 pub fn get_ref(&self) -> &BitSet {
36 &self.inner
37 }
38
39 pub fn from_bit_set(inner: BitSet) -> Self {
41 Self {
42 inner,
43 _phantom: PhantomData,
44 }
45 }
46
47 pub fn new() -> Self {
49 Self {
50 inner: BitSet::new(),
52 _phantom: PhantomData,
53 }
54 }
55
56 pub fn shrink_to_fit(&mut self) {
58 self.inner.shrink_to_fit()
59 }
60
61 pub fn iter(&self) -> WrapIter<E, bit_set::Iter<'_, u32>> {
63 WrapIter::<E, _>::new(self.inner.iter())
64 }
65
66 pub fn union<'a>(&'a self, other: &'a Self) -> Union<'a, E> {
76 WrapIter::<E, _>::new(self.inner.union(&other.inner))
77 }
78
79 pub fn intersection<'a>(&'a self, other: &'a Self) -> Intersection<'a, E> {
81 WrapIter::<E, _>::new(self.inner.intersection(&other.inner))
82 }
83
84 pub fn difference<'a>(&'a self, other: &'a Self) -> Difference<'a, E> {
86 WrapIter::<E, _>::new(self.inner.difference(&other.inner))
87 }
88
89 pub fn symmetric_difference<'a>(&'a self, other: &'a Self) -> SymmetricDifference<'a, E> {
91 WrapIter::<E, _>::new(self.inner.symmetric_difference(&other.inner))
92 }
93
94 pub fn union_with(&mut self, other: &Self) {
96 self.inner.union_with(&other.inner)
97 }
98
99 pub fn intersect_with(&mut self, other: &Self) {
101 self.inner.intersect_with(&other.inner)
102 }
103
104 pub fn difference_with(&mut self, other: &Self) {
106 self.inner.difference_with(&other.inner)
107 }
108
109 pub fn symmetric_difference_with(&mut self, other: &Self) {
111 self.inner.symmetric_difference_with(&other.inner)
112 }
113
114 pub fn len(&self) -> usize {
116 self.inner.len()
117 }
118
119 pub fn is_empty(&self) -> bool {
121 self.inner.is_empty()
122 }
123
124 pub fn clear(&mut self) {
126 self.inner.clear()
127 }
128
129 pub fn contains(&self, value: E) -> bool {
131 let d = value.to_discr();
132 self.inner.contains(d)
133 }
134
135 pub fn is_disjoint(&self, other: &Self) -> bool {
137 self.inner.is_disjoint(&other.inner)
138 }
139
140 pub fn is_subset(&self, other: &Self) -> bool {
142 self.inner.is_subset(&other.inner)
143 }
144
145 pub fn is_superset(&self, other: &Self) -> bool {
147 self.inner.is_superset(&other.inner)
148 }
149
150 pub fn insert(&mut self, value: E) -> bool {
152 let d = value.to_discr();
153 self.inner.insert(d)
154 }
155
156 pub fn remove(&mut self, value: E) -> bool {
158 let d = value.to_discr();
159 self.inner.remove(d)
160 }
161}
162
163impl<E: EnumLike> Default for EnumSet<E> {
164 fn default() -> Self {
165 Self::new()
166 }
167}
168
169impl<E: EnumLike> FromIterator<E> for EnumSet<E> {
170 fn from_iter<I: IntoIterator<Item = E>>(iter: I) -> Self {
171 let mut ret = Self::default();
172 ret.extend(iter);
173 ret
174 }
175}
176
177impl<E: EnumLike> Extend<E> for EnumSet<E> {
178 fn extend<I: IntoIterator<Item = E>>(&mut self, iter: I) {
179 for i in iter {
180 self.insert(i);
181 }
182 }
183}
184
185impl<E: EnumLike + fmt::Debug> fmt::Debug for EnumSet<E> {
186 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
187 f.debug_set().entries(self.iter()).finish()
188 }
189}
190
191#[derive(Debug)]
196pub struct WrapIter<E: EnumLike, I: Iterator<Item=usize>> {
197 inner: I,
198 _phantom: PhantomData<E>,
199}
200
201pub type Iter<'a, E> = WrapIter<E, bit_set::Iter<'a, u32>>;
203pub type Union<'a, E> = WrapIter<E, bit_set::Union<'a, u32>>;
205pub type Intersection<'a, E> = WrapIter<E, bit_set::Intersection<'a, u32>>;
207pub type Difference<'a, E> = WrapIter<E, bit_set::Difference<'a, u32>>;
209pub type SymmetricDifference<'a, E> = WrapIter<E, bit_set::SymmetricDifference<'a, u32>>;
211
212impl<E: EnumLike, I: Iterator<Item=usize>> WrapIter<E, I> {
213 fn new(inner: I) -> Self {
214 Self { inner, _phantom: PhantomData }
215 }
216}
217
218impl<E: EnumLike, I: Iterator<Item=usize>> Iterator for WrapIter<E, I> {
219 type Item = E;
220 fn next(&mut self) -> Option<E> {
221 self.inner.next().map(|x| E::from_discr(x))
222 }
223 fn size_hint(&self) -> (usize, Option<usize>) {
224 self.inner.size_hint()
225 }
226}
227
228impl<'a, E: EnumLike> IntoIterator for &'a EnumSet<E> {
229 type Item = E;
230 type IntoIter = WrapIter<E, bit_set::Iter<'a, u32>>;
231
232 fn into_iter(self) -> Self::IntoIter {
233 self.iter()
234 }
235}
236
237
238#[cfg(test)]
257mod tests {
258 use super::*;
259
260 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
261 enum ABC {
262 A,
263 B,
264 C,
265 }
266
267 unsafe impl EnumLike for ABC {
268 const NUM_VARIANTS: usize = 3;
269 fn to_discr(self) -> usize {
270 match self {
274 ABC::A => 0,
275 ABC::B => 1,
276 ABC::C => 2,
277 }
278 }
279 fn from_discr(x: usize) -> Self {
280 match x {
281 0 => ABC::A,
282 1 => ABC::B,
283 2 => ABC::C,
284 _ => panic!("Enum ABC has no variant {}", x),
285 }
286 }
287 }
288
289 #[test]
290 fn create() {
291 let mut e = EnumSet::new();
292 assert_eq!(e.contains(ABC::A), false);
293 assert_eq!(e.insert(ABC::A), true);
294 assert_eq!(e.insert(ABC::A), false);
295 assert_eq!(e.contains(ABC::A), true);
296 assert_eq!(e.remove(ABC::A), true);
297 assert_eq!(e.remove(ABC::A), false);
298 assert_eq!(e.contains(ABC::A), false);
299 }
300
301 }