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 //! A structure for holding a set of enum variants.
13 //! This module defines a container which uses an efficient bit mask
14 //! representation to hold C-like enum variants.
19 use core::iter::FromIterator;
20 use core::ops::{Sub, BitOr, BitAnd, BitXor};
22 // FIXME(contentions): implement union family of methods? (general design may be wrong here)
24 #[deriving(Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
25 /// A specialized set implementation to use enum types.
26 pub struct EnumSet<E> {
27 // We must maintain the invariant that no bits are set
28 // for which no variant exists
32 impl<E> Copy for EnumSet<E> {}
34 impl<E:CLike+fmt::Show> fmt::Show for EnumSet<E> {
35 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
36 try!(write!(fmt, "{{"));
38 for e in self.iter() {
40 try!(write!(fmt, ", "));
42 try!(write!(fmt, "{}", e));
49 /// An interface for casting C-like enum to uint and back.
50 /// A typically implementation is as below.
58 /// impl CLike for Foo {
59 /// fn to_uint(&self) -> uint {
63 /// fn from_uint(v: uint) -> Foo {
64 /// unsafe { mem::transmute(v) }
69 /// Converts a C-like enum to a `uint`.
70 fn to_uint(&self) -> uint;
71 /// Converts a `uint` to a C-like enum.
72 fn from_uint(uint) -> Self;
75 fn bit<E:CLike>(e: &E) -> uint {
77 let value = e.to_uint();
78 assert!(value < uint::BITS,
79 "EnumSet only supports up to {} variants.", uint::BITS - 1);
83 impl<E:CLike> EnumSet<E> {
84 /// Deprecated: Renamed to `new`.
85 #[deprecated = "Renamed to `new`"]
86 pub fn empty() -> EnumSet<E> {
90 /// Returns an empty `EnumSet`.
91 #[unstable = "matches collection reform specification, waiting for dust to settle"]
92 pub fn new() -> EnumSet<E> {
96 /// Returns the number of elements in the given `EnumSet`.
97 #[unstable = "matches collection reform specification, waiting for dust to settle"]
98 pub fn len(&self) -> uint {
99 self.bits.count_ones()
102 /// Returns true if the `EnumSet` is empty.
103 #[unstable = "matches collection reform specification, waiting for dust to settle"]
104 pub fn is_empty(&self) -> bool {
108 pub fn clear(&mut self) {
112 /// Returns `true` if the `EnumSet` contains any enum of the given `EnumSet`.
113 /// Deprecated: Use `is_disjoint`.
114 #[deprecated = "Use `is_disjoint`"]
115 pub fn intersects(&self, e: EnumSet<E>) -> bool {
116 !self.is_disjoint(&e)
119 /// Returns `false` if the `EnumSet` contains any enum of the given `EnumSet`.
120 #[unstable = "matches collection reform specification, waiting for dust to settle"]
121 pub fn is_disjoint(&self, other: &EnumSet<E>) -> bool {
122 (self.bits & other.bits) == 0
125 /// Returns `true` if a given `EnumSet` is included in this `EnumSet`.
126 #[unstable = "matches collection reform specification, waiting for dust to settle"]
127 pub fn is_superset(&self, other: &EnumSet<E>) -> bool {
128 (self.bits & other.bits) == other.bits
131 /// Returns `true` if this `EnumSet` is included in the given `EnumSet`.
132 #[unstable = "matches collection reform specification, waiting for dust to settle"]
133 pub fn is_subset(&self, other: &EnumSet<E>) -> bool {
134 other.is_superset(self)
137 /// Returns the union of both `EnumSets`.
138 pub fn union(&self, e: EnumSet<E>) -> EnumSet<E> {
139 EnumSet {bits: self.bits | e.bits}
142 /// Returns the intersection of both `EnumSets`.
143 pub fn intersection(&self, e: EnumSet<E>) -> EnumSet<E> {
144 EnumSet {bits: self.bits & e.bits}
147 /// Deprecated: Use `insert`.
148 #[deprecated = "Use `insert`"]
149 pub fn add(&mut self, e: E) {
153 /// Adds an enum to the `EnumSet`, and returns `true` if it wasn't there before
154 #[unstable = "matches collection reform specification, waiting for dust to settle"]
155 pub fn insert(&mut self, e: E) -> bool {
156 let result = !self.contains(&e);
157 self.bits |= bit(&e);
161 /// Removes an enum from the EnumSet
162 #[unstable = "matches collection reform specification, waiting for dust to settle"]
163 pub fn remove(&mut self, e: &E) -> bool {
164 let result = self.contains(e);
165 self.bits &= !bit(e);
169 /// Deprecated: use `contains`.
170 #[deprecated = "use `contains"]
171 pub fn contains_elem(&self, e: E) -> bool {
175 /// Returns `true` if an `EnumSet` contains a given enum.
176 #[unstable = "matches collection reform specification, waiting for dust to settle"]
177 pub fn contains(&self, e: &E) -> bool {
178 (self.bits & bit(e)) != 0
181 /// Returns an iterator over an `EnumSet`.
182 #[unstable = "matches collection reform specification, waiting for dust to settle"]
183 pub fn iter(&self) -> Iter<E> {
188 impl<E:CLike> Sub for EnumSet<E> {
189 type Output = EnumSet<E>;
191 fn sub(self, e: EnumSet<E>) -> EnumSet<E> {
192 EnumSet {bits: self.bits & !e.bits}
196 impl<E:CLike> BitOr for EnumSet<E> {
197 type Output = EnumSet<E>;
199 fn bitor(self, e: EnumSet<E>) -> EnumSet<E> {
200 EnumSet {bits: self.bits | e.bits}
204 impl<E:CLike> BitAnd for EnumSet<E> {
205 type Output = EnumSet<E>;
207 fn bitand(self, e: EnumSet<E>) -> EnumSet<E> {
208 EnumSet {bits: self.bits & e.bits}
212 impl<E:CLike> BitXor for EnumSet<E> {
213 type Output = EnumSet<E>;
215 fn bitxor(self, e: EnumSet<E>) -> EnumSet<E> {
216 EnumSet {bits: self.bits ^ e.bits}
220 /// An iterator over an EnumSet
226 // FIXME(#19839) Remove in favor of `#[deriving(Clone)]`
227 impl<E> Clone for Iter<E> {
228 fn clone(&self) -> Iter<E> {
236 impl<E:CLike> Iter<E> {
237 fn new(bits: uint) -> Iter<E> {
238 Iter { index: 0, bits: bits }
242 impl<E:CLike> Iterator for Iter<E> {
245 fn next(&mut self) -> Option<E> {
250 while (self.bits & 1) == 0 {
254 let elem = CLike::from_uint(self.index);
260 fn size_hint(&self) -> (uint, Option<uint>) {
261 let exact = self.bits.count_ones();
266 impl<E:CLike> FromIterator<E> for EnumSet<E> {
267 fn from_iter<I:Iterator<Item=E>>(iterator: I) -> EnumSet<E> {
268 let mut ret = EnumSet::new();
269 ret.extend(iterator);
274 impl<E:CLike> Extend<E> for EnumSet<E> {
275 fn extend<I: Iterator<Item=E>>(&mut self, mut iterator: I) {
276 for element in iterator {
277 self.insert(element);
288 use super::{EnumSet, CLike};
290 #[deriving(Copy, PartialEq, Show)]
297 fn to_uint(&self) -> uint {
301 fn from_uint(v: uint) -> Foo {
302 unsafe { mem::transmute(v) }
308 let e: EnumSet<Foo> = EnumSet::new();
309 assert!(e.is_empty());
314 let mut e = EnumSet::new();
315 assert_eq!("{}", e.to_string());
317 assert_eq!("{A}", e.to_string());
319 assert_eq!("{A, C}", e.to_string());
324 let mut e = EnumSet::new();
325 assert_eq!(e.len(), 0);
329 assert_eq!(e.len(), 3);
331 assert_eq!(e.len(), 2);
333 assert_eq!(e.len(), 0);
336 ///////////////////////////////////////////////////////////////////////////
340 fn test_two_empties_do_not_intersect() {
341 let e1: EnumSet<Foo> = EnumSet::new();
342 let e2: EnumSet<Foo> = EnumSet::new();
343 assert!(e1.is_disjoint(&e2));
347 fn test_empty_does_not_intersect_with_full() {
348 let e1: EnumSet<Foo> = EnumSet::new();
350 let mut e2: EnumSet<Foo> = EnumSet::new();
355 assert!(e1.is_disjoint(&e2));
359 fn test_disjoint_intersects() {
360 let mut e1: EnumSet<Foo> = EnumSet::new();
363 let mut e2: EnumSet<Foo> = EnumSet::new();
366 assert!(e1.is_disjoint(&e2));
370 fn test_overlapping_intersects() {
371 let mut e1: EnumSet<Foo> = EnumSet::new();
374 let mut e2: EnumSet<Foo> = EnumSet::new();
378 assert!(!e1.is_disjoint(&e2));
381 ///////////////////////////////////////////////////////////////////////////
382 // contains and contains_elem
386 let mut e1: EnumSet<Foo> = EnumSet::new();
389 let mut e2: EnumSet<Foo> = EnumSet::new();
393 let mut e3: EnumSet<Foo> = EnumSet::new();
396 assert!(e1.is_subset(&e2));
397 assert!(e2.is_superset(&e1));
398 assert!(!e3.is_superset(&e2));
399 assert!(!e2.is_superset(&e3))
404 let mut e1: EnumSet<Foo> = EnumSet::new();
406 assert!(e1.contains(&A));
407 assert!(!e1.contains(&B));
408 assert!(!e1.contains(&C));
412 assert!(e1.contains(&A));
413 assert!(e1.contains(&B));
414 assert!(!e1.contains(&C));
417 ///////////////////////////////////////////////////////////////////////////
422 let mut e1: EnumSet<Foo> = EnumSet::new();
424 let elems: ::vec::Vec<Foo> = e1.iter().collect();
425 assert!(elems.is_empty());
428 let elems: ::vec::Vec<_> = e1.iter().collect();
429 assert_eq!(vec![A], elems);
432 let elems: ::vec::Vec<_> = e1.iter().collect();
433 assert_eq!(vec![A,C], elems);
436 let elems: ::vec::Vec<_> = e1.iter().collect();
437 assert_eq!(vec![A,C], elems);
440 let elems: ::vec::Vec<_> = e1.iter().collect();
441 assert_eq!(vec![A,B,C], elems);
444 ///////////////////////////////////////////////////////////////////////////
448 fn test_operators() {
449 let mut e1: EnumSet<Foo> = EnumSet::new();
453 let mut e2: EnumSet<Foo> = EnumSet::new();
457 let e_union = e1 | e2;
458 let elems: ::vec::Vec<_> = e_union.iter().collect();
459 assert_eq!(vec![A,B,C], elems);
461 let e_intersection = e1 & e2;
462 let elems: ::vec::Vec<_> = e_intersection.iter().collect();
463 assert_eq!(vec![C], elems);
465 // Another way to express intersection
466 let e_intersection = e1 - (e1 - e2);
467 let elems: ::vec::Vec<_> = e_intersection.iter().collect();
468 assert_eq!(vec![C], elems);
470 let e_subtract = e1 - e2;
471 let elems: ::vec::Vec<_> = e_subtract.iter().collect();
472 assert_eq!(vec![A], elems);
474 // Bitwise XOR of two sets, aka symmetric difference
475 let e_symmetric_diff = e1 ^ e2;
476 let elems: ::vec::Vec<_> = e_symmetric_diff.iter().collect();
477 assert_eq!(vec![A,B], elems);
479 // Another way to express symmetric difference
480 let e_symmetric_diff = (e1 - e2) | (e2 - e1);
481 let elems: ::vec::Vec<_> = e_symmetric_diff.iter().collect();
482 assert_eq!(vec![A,B], elems);
484 // Yet another way to express symmetric difference
485 let e_symmetric_diff = (e1 | e2) - (e1 & e2);
486 let elems: ::vec::Vec<_> = e_symmetric_diff.iter().collect();
487 assert_eq!(vec![A,B], elems);
497 V00, V01, V02, V03, V04, V05, V06, V07, V08, V09,
498 V10, V11, V12, V13, V14, V15, V16, V17, V18, V19,
499 V20, V21, V22, V23, V24, V25, V26, V27, V28, V29,
500 V30, V31, V32, V33, V34, V35, V36, V37, V38, V39,
501 V40, V41, V42, V43, V44, V45, V46, V47, V48, V49,
502 V50, V51, V52, V53, V54, V55, V56, V57, V58, V59,
503 V60, V61, V62, V63, V64, V65, V66, V67, V68, V69,
507 fn to_uint(&self) -> uint {
511 fn from_uint(v: uint) -> Bar {
512 unsafe { mem::transmute(v) }
515 let mut set = EnumSet::new();
516 set.insert(Bar::V64);