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.
20 // FIXME(contentions): implement union family of methods? (general design may be wrong here)
22 #[deriving(Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
23 /// A specialized `Set` implementation to use enum types.
24 pub struct EnumSet<E> {
25 // We must maintain the invariant that no bits are set
26 // for which no variant exists
30 impl<E> Copy for EnumSet<E> {}
32 impl<E:CLike+fmt::Show> fmt::Show for EnumSet<E> {
33 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
34 try!(write!(fmt, "{{"));
36 for e in self.iter() {
38 try!(write!(fmt, ", "));
40 try!(write!(fmt, "{}", e));
47 /// An interface for casting C-like enum to uint and back.
48 /// A typically implementation is as below.
56 /// impl CLike for Foo {
57 /// fn to_uint(&self) -> uint {
61 /// fn from_uint(v: uint) -> Foo {
62 /// unsafe { mem::transmute(v) }
67 /// Converts a C-like enum to a `uint`.
68 fn to_uint(&self) -> uint;
69 /// Converts a `uint` to a C-like enum.
70 fn from_uint(uint) -> Self;
73 fn bit<E:CLike>(e: &E) -> uint {
75 let value = e.to_uint();
76 assert!(value < uint::BITS,
77 "EnumSet only supports up to {} variants.", uint::BITS - 1);
81 impl<E:CLike> EnumSet<E> {
82 /// Deprecated: Renamed to `new`.
83 #[deprecated = "Renamed to `new`"]
84 pub fn empty() -> EnumSet<E> {
88 /// Returns an empty `EnumSet`.
89 #[unstable = "matches collection reform specification, waiting for dust to settle"]
90 pub fn new() -> EnumSet<E> {
94 /// Returns the number of elements in the given `EnumSet`.
95 #[unstable = "matches collection reform specification, waiting for dust to settle"]
96 pub fn len(&self) -> uint {
97 self.bits.count_ones()
100 /// Returns true if the `EnumSet` is empty.
101 #[unstable = "matches collection reform specification, waiting for dust to settle"]
102 pub fn is_empty(&self) -> bool {
106 pub fn clear(&mut self) {
110 /// Returns `true` if the `EnumSet` contains any enum of the given `EnumSet`.
111 /// Deprecated: Use `is_disjoint`.
112 #[deprecated = "Use `is_disjoint`"]
113 pub fn intersects(&self, e: EnumSet<E>) -> bool {
114 !self.is_disjoint(&e)
117 /// Returns `false` if the `EnumSet` contains any enum of the given `EnumSet`.
118 #[unstable = "matches collection reform specification, waiting for dust to settle"]
119 pub fn is_disjoint(&self, other: &EnumSet<E>) -> bool {
120 (self.bits & other.bits) == 0
123 /// Returns `true` if a given `EnumSet` is included in this `EnumSet`.
124 #[unstable = "matches collection reform specification, waiting for dust to settle"]
125 pub fn is_superset(&self, other: &EnumSet<E>) -> bool {
126 (self.bits & other.bits) == other.bits
129 /// Returns `true` if this `EnumSet` is included in the given `EnumSet`.
130 #[unstable = "matches collection reform specification, waiting for dust to settle"]
131 pub fn is_subset(&self, other: &EnumSet<E>) -> bool {
132 other.is_superset(self)
135 /// Returns the union of both `EnumSets`.
136 pub fn union(&self, e: EnumSet<E>) -> EnumSet<E> {
137 EnumSet {bits: self.bits | e.bits}
140 /// Returns the intersection of both `EnumSets`.
141 pub fn intersection(&self, e: EnumSet<E>) -> EnumSet<E> {
142 EnumSet {bits: self.bits & e.bits}
145 /// Deprecated: Use `insert`.
146 #[deprecated = "Use `insert`"]
147 pub fn add(&mut self, e: E) {
151 /// Adds an enum to the `EnumSet`, and returns `true` if it wasn't there before
152 #[unstable = "matches collection reform specification, waiting for dust to settle"]
153 pub fn insert(&mut self, e: E) -> bool {
154 let result = !self.contains(&e);
155 self.bits |= bit(&e);
159 /// Removes an enum from the EnumSet
160 #[unstable = "matches collection reform specification, waiting for dust to settle"]
161 pub fn remove(&mut self, e: &E) -> bool {
162 let result = self.contains(e);
163 self.bits &= !bit(e);
167 /// Deprecated: use `contains`.
168 #[deprecated = "use `contains"]
169 pub fn contains_elem(&self, e: E) -> bool {
173 /// Returns `true` if an `EnumSet` contains a given enum.
174 #[unstable = "matches collection reform specification, waiting for dust to settle"]
175 pub fn contains(&self, e: &E) -> bool {
176 (self.bits & bit(e)) != 0
179 /// Returns an iterator over an `EnumSet`.
180 #[unstable = "matches collection reform specification, waiting for dust to settle"]
181 pub fn iter(&self) -> Items<E> {
182 Items::new(self.bits)
186 impl<E:CLike> Sub<EnumSet<E>, EnumSet<E>> for EnumSet<E> {
187 fn sub(&self, e: &EnumSet<E>) -> EnumSet<E> {
188 EnumSet {bits: self.bits & !e.bits}
192 impl<E:CLike> BitOr<EnumSet<E>, EnumSet<E>> for EnumSet<E> {
193 fn bitor(&self, e: &EnumSet<E>) -> EnumSet<E> {
194 EnumSet {bits: self.bits | e.bits}
198 impl<E:CLike> BitAnd<EnumSet<E>, EnumSet<E>> for EnumSet<E> {
199 fn bitand(&self, e: &EnumSet<E>) -> EnumSet<E> {
200 EnumSet {bits: self.bits & e.bits}
204 impl<E:CLike> BitXor<EnumSet<E>, EnumSet<E>> for EnumSet<E> {
205 fn bitxor(&self, e: &EnumSet<E>) -> EnumSet<E> {
206 EnumSet {bits: self.bits ^ e.bits}
210 /// An iterator over an EnumSet
211 pub struct Items<E> {
216 impl<E:CLike> Items<E> {
217 fn new(bits: uint) -> Items<E> {
218 Items { index: 0, bits: bits }
222 impl<E:CLike> Iterator<E> for Items<E> {
223 fn next(&mut self) -> Option<E> {
228 while (self.bits & 1) == 0 {
232 let elem = CLike::from_uint(self.index);
238 fn size_hint(&self) -> (uint, Option<uint>) {
239 let exact = self.bits.count_ones();
244 impl<E:CLike> FromIterator<E> for EnumSet<E> {
245 fn from_iter<I:Iterator<E>>(iterator: I) -> EnumSet<E> {
246 let mut ret = EnumSet::new();
247 ret.extend(iterator);
252 impl<E:CLike> Extend<E> for EnumSet<E> {
253 fn extend<I: Iterator<E>>(&mut self, mut iterator: I) {
254 for element in iterator {
255 self.insert(element);
266 use super::{EnumSet, CLike};
268 #[deriving(PartialEq, Show)]
277 fn to_uint(&self) -> uint {
281 fn from_uint(v: uint) -> Foo {
282 unsafe { mem::transmute(v) }
288 let e: EnumSet<Foo> = EnumSet::new();
289 assert!(e.is_empty());
294 let mut e = EnumSet::new();
295 assert_eq!("{}", e.to_string());
297 assert_eq!("{A}", e.to_string());
299 assert_eq!("{A, C}", e.to_string());
304 let mut e = EnumSet::new();
305 assert_eq!(e.len(), 0);
309 assert_eq!(e.len(), 3);
311 assert_eq!(e.len(), 2);
313 assert_eq!(e.len(), 0);
316 ///////////////////////////////////////////////////////////////////////////
320 fn test_two_empties_do_not_intersect() {
321 let e1: EnumSet<Foo> = EnumSet::new();
322 let e2: EnumSet<Foo> = EnumSet::new();
323 assert!(e1.is_disjoint(&e2));
327 fn test_empty_does_not_intersect_with_full() {
328 let e1: EnumSet<Foo> = EnumSet::new();
330 let mut e2: EnumSet<Foo> = EnumSet::new();
335 assert!(e1.is_disjoint(&e2));
339 fn test_disjoint_intersects() {
340 let mut e1: EnumSet<Foo> = EnumSet::new();
343 let mut e2: EnumSet<Foo> = EnumSet::new();
346 assert!(e1.is_disjoint(&e2));
350 fn test_overlapping_intersects() {
351 let mut e1: EnumSet<Foo> = EnumSet::new();
354 let mut e2: EnumSet<Foo> = EnumSet::new();
358 assert!(!e1.is_disjoint(&e2));
361 ///////////////////////////////////////////////////////////////////////////
362 // contains and contains_elem
366 let mut e1: EnumSet<Foo> = EnumSet::new();
369 let mut e2: EnumSet<Foo> = EnumSet::new();
373 let mut e3: EnumSet<Foo> = EnumSet::new();
376 assert!(e1.is_subset(&e2));
377 assert!(e2.is_superset(&e1));
378 assert!(!e3.is_superset(&e2))
379 assert!(!e2.is_superset(&e3))
384 let mut e1: EnumSet<Foo> = EnumSet::new();
386 assert!(e1.contains(&A));
387 assert!(!e1.contains(&B));
388 assert!(!e1.contains(&C));
392 assert!(e1.contains(&A));
393 assert!(e1.contains(&B));
394 assert!(!e1.contains(&C));
397 ///////////////////////////////////////////////////////////////////////////
402 let mut e1: EnumSet<Foo> = EnumSet::new();
404 let elems: ::vec::Vec<Foo> = e1.iter().collect();
405 assert!(elems.is_empty())
408 let elems: ::vec::Vec<_> = e1.iter().collect();
409 assert_eq!(vec![A], elems)
412 let elems: ::vec::Vec<_> = e1.iter().collect();
413 assert_eq!(vec![A,C], elems)
416 let elems: ::vec::Vec<_> = e1.iter().collect();
417 assert_eq!(vec![A,C], elems)
420 let elems: ::vec::Vec<_> = e1.iter().collect();
421 assert_eq!(vec![A,B,C], elems)
424 ///////////////////////////////////////////////////////////////////////////
428 fn test_operators() {
429 let mut e1: EnumSet<Foo> = EnumSet::new();
433 let mut e2: EnumSet<Foo> = EnumSet::new();
437 let e_union = e1 | e2;
438 let elems: ::vec::Vec<_> = e_union.iter().collect();
439 assert_eq!(vec![A,B,C], elems)
441 let e_intersection = e1 & e2;
442 let elems: ::vec::Vec<_> = e_intersection.iter().collect();
443 assert_eq!(vec![C], elems)
445 // Another way to express intersection
446 let e_intersection = e1 - (e1 - e2);
447 let elems: ::vec::Vec<_> = e_intersection.iter().collect();
448 assert_eq!(vec![C], elems)
450 let e_subtract = e1 - e2;
451 let elems: ::vec::Vec<_> = e_subtract.iter().collect();
452 assert_eq!(vec![A], elems)
454 // Bitwise XOR of two sets, aka symmetric difference
455 let e_symmetric_diff = e1 ^ e2;
456 let elems: ::vec::Vec<_> = e_symmetric_diff.iter().collect();
457 assert_eq!(vec![A,B], elems)
459 // Another way to express symmetric difference
460 let e_symmetric_diff = (e1 - e2) | (e2 - e1);
461 let elems: ::vec::Vec<_> = e_symmetric_diff.iter().collect();
462 assert_eq!(vec![A,B], elems)
464 // Yet another way to express symmetric difference
465 let e_symmetric_diff = (e1 | e2) - (e1 & e2);
466 let elems: ::vec::Vec<_> = e_symmetric_diff.iter().collect();
467 assert_eq!(vec![A,B], elems)
476 V00, V01, V02, V03, V04, V05, V06, V07, V08, V09,
477 V10, V11, V12, V13, V14, V15, V16, V17, V18, V19,
478 V20, V21, V22, V23, V24, V25, V26, V27, V28, V29,
479 V30, V31, V32, V33, V34, V35, V36, V37, V38, V39,
480 V40, V41, V42, V43, V44, V45, V46, V47, V48, V49,
481 V50, V51, V52, V53, V54, V55, V56, V57, V58, V59,
482 V60, V61, V62, V63, V64, V65, V66, V67, V68, V69,
488 fn to_uint(&self) -> uint {
492 fn from_uint(v: uint) -> Bar {
493 unsafe { mem::transmute(v) }
496 let mut set = EnumSet::new();
497 set.insert(Bar::V64);