1 // Copyright 2012 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
11 use std::iterator::Iterator;
13 #[deriving(Clone, Eq, IterBytes, ToStr)]
14 pub struct EnumSet<E> {
15 // We must maintain the invariant that no bits are set
16 // for which no variant exists
21 pub fn to_uint(&self) -> uint;
22 pub fn from_uint(uint) -> Self;
25 fn bit<E:CLike>(e: E) -> uint {
29 impl<E:CLike> EnumSet<E> {
30 pub fn empty() -> EnumSet<E> {
34 pub fn is_empty(&self) -> bool {
38 pub fn intersects(&self, e: EnumSet<E>) -> bool {
39 (self.bits & e.bits) != 0
42 pub fn intersection(&self, e: EnumSet<E>) -> EnumSet<E> {
43 EnumSet {bits: self.bits & e.bits}
46 pub fn contains(&self, e: EnumSet<E>) -> bool {
47 (self.bits & e.bits) == e.bits
50 pub fn union(&self, e: EnumSet<E>) -> EnumSet<E> {
51 EnumSet {bits: self.bits | e.bits}
54 pub fn add(&mut self, e: E) {
58 pub fn contains_elem(&self, e: E) -> bool {
59 (self.bits & bit(e)) != 0
62 pub fn each(&self, f: &fn(E) -> bool) -> bool {
63 let mut bits = self.bits;
67 let e = CLike::from_uint(index);
78 pub fn iter(&self) -> EnumSetIterator<E> {
79 EnumSetIterator::new(self.bits)
83 impl<E:CLike> Sub<EnumSet<E>, EnumSet<E>> for EnumSet<E> {
84 fn sub(&self, e: &EnumSet<E>) -> EnumSet<E> {
85 EnumSet {bits: self.bits & !e.bits}
89 impl<E:CLike> BitOr<EnumSet<E>, EnumSet<E>> for EnumSet<E> {
90 fn bitor(&self, e: &EnumSet<E>) -> EnumSet<E> {
91 EnumSet {bits: self.bits | e.bits}
95 impl<E:CLike> BitAnd<EnumSet<E>, EnumSet<E>> for EnumSet<E> {
96 fn bitand(&self, e: &EnumSet<E>) -> EnumSet<E> {
97 EnumSet {bits: self.bits & e.bits}
101 pub struct EnumSetIterator<E> {
106 impl<E:CLike> EnumSetIterator<E> {
107 fn new(bits: uint) -> EnumSetIterator<E> {
108 EnumSetIterator { index: 0, bits: bits }
112 impl<E:CLike> Iterator<E> for EnumSetIterator<E> {
113 fn next(&mut self) -> Option<E> {
114 if (self.bits == 0) {
118 while (self.bits & 1) == 0 {
122 let elem = CLike::from_uint(self.index);
128 fn size_hint(&self) -> (uint, Option<uint>) {
129 let exact = self.bits.population_count();
139 use util::enum_set::*;
147 pub fn to_uint(&self) -> uint {
151 pub fn from_uint(v: uint) -> Foo {
152 unsafe { cast::transmute(v) }
158 let e: EnumSet<Foo> = EnumSet::empty();
159 assert!(e.is_empty());
162 ///////////////////////////////////////////////////////////////////////////
166 fn test_two_empties_do_not_intersect() {
167 let e1: EnumSet<Foo> = EnumSet::empty();
168 let e2: EnumSet<Foo> = EnumSet::empty();
169 assert!(!e1.intersects(e2));
173 fn test_empty_does_not_intersect_with_full() {
174 let e1: EnumSet<Foo> = EnumSet::empty();
176 let mut e2: EnumSet<Foo> = EnumSet::empty();
181 assert!(!e1.intersects(e2));
185 fn test_disjoint_intersects() {
186 let mut e1: EnumSet<Foo> = EnumSet::empty();
189 let mut e2: EnumSet<Foo> = EnumSet::empty();
192 assert!(!e1.intersects(e2));
196 fn test_overlapping_intersects() {
197 let mut e1: EnumSet<Foo> = EnumSet::empty();
200 let mut e2: EnumSet<Foo> = EnumSet::empty();
204 assert!(e1.intersects(e2));
207 ///////////////////////////////////////////////////////////////////////////
208 // contains and contains_elem
212 let mut e1: EnumSet<Foo> = EnumSet::empty();
215 let mut e2: EnumSet<Foo> = EnumSet::empty();
219 assert!(!e1.contains(e2));
220 assert!(e2.contains(e1));
224 fn test_contains_elem() {
225 let mut e1: EnumSet<Foo> = EnumSet::empty();
227 assert!(e1.contains_elem(A));
228 assert!(!e1.contains_elem(B));
229 assert!(!e1.contains_elem(C));
233 assert!(e1.contains_elem(A));
234 assert!(e1.contains_elem(B));
235 assert!(!e1.contains_elem(C));
238 ///////////////////////////////////////////////////////////////////////////
243 let mut e1: EnumSet<Foo> = EnumSet::empty();
245 let elems: ~[Foo] = e1.iter().collect();
246 assert_eq!(~[], elems)
249 let elems: ~[Foo] = e1.iter().collect();
250 assert_eq!(~[A], elems)
253 let elems: ~[Foo] = e1.iter().collect();
254 assert_eq!(~[A,C], elems)
257 let elems: ~[Foo] = e1.iter().collect();
258 assert_eq!(~[A,C], elems)
261 let elems: ~[Foo] = e1.iter().collect();
262 assert_eq!(~[A,B,C], elems)
267 let mut e1: EnumSet<Foo> = EnumSet::empty();
269 assert_eq!(~[], collect(e1))
272 assert_eq!(~[A], collect(e1))
275 assert_eq!(~[A,C], collect(e1))
278 assert_eq!(~[A,C], collect(e1))
281 assert_eq!(~[A,B,C], collect(e1))
284 fn collect(e: EnumSet<Foo>) -> ~[Foo] {
293 ///////////////////////////////////////////////////////////////////////////
297 fn test_operators() {
298 let mut e1: EnumSet<Foo> = EnumSet::empty();
302 let mut e2: EnumSet<Foo> = EnumSet::empty();
306 let e_union = e1 | e2;
307 let elems: ~[Foo] = e_union.iter().collect();
308 assert_eq!(~[A,B,C], elems)
310 let e_intersection = e1 & e2;
311 let elems: ~[Foo] = e_intersection.iter().collect();
312 assert_eq!(~[C], elems)
314 let e_subtract = e1 - e2;
315 let elems: ~[Foo] = e_subtract.iter().collect();
316 assert_eq!(~[A], elems)