2015-03-10 23:58:16 -05:00
|
|
|
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
|
|
|
|
// file at the top-level directory of this distribution and at
|
|
|
|
// http://rust-lang.org/COPYRIGHT.
|
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
|
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
|
|
// option. This file may not be copied, modified, or distributed
|
|
|
|
// except according to those terms.
|
|
|
|
|
2015-03-11 19:28:58 -05:00
|
|
|
use std::mem;
|
|
|
|
|
|
|
|
use collections::enum_set::{CLike, EnumSet};
|
|
|
|
|
|
|
|
use self::Foo::*;
|
2015-03-10 23:58:16 -05:00
|
|
|
|
2015-03-30 08:40:52 -05:00
|
|
|
#[derive(Copy, Clone, PartialEq, Debug)]
|
2015-03-10 23:58:16 -05:00
|
|
|
#[repr(usize)]
|
|
|
|
enum Foo {
|
|
|
|
A, B, C
|
|
|
|
}
|
|
|
|
|
|
|
|
impl CLike for Foo {
|
|
|
|
fn to_usize(&self) -> usize {
|
|
|
|
*self as usize
|
|
|
|
}
|
|
|
|
|
|
|
|
fn from_usize(v: usize) -> Foo {
|
|
|
|
unsafe { mem::transmute(v) }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_new() {
|
|
|
|
let e: EnumSet<Foo> = EnumSet::new();
|
|
|
|
assert!(e.is_empty());
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_show() {
|
|
|
|
let mut e = EnumSet::new();
|
|
|
|
assert!(format!("{:?}", e) == "{}");
|
|
|
|
e.insert(A);
|
|
|
|
assert!(format!("{:?}", e) == "{A}");
|
|
|
|
e.insert(C);
|
|
|
|
assert!(format!("{:?}", e) == "{A, C}");
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_len() {
|
|
|
|
let mut e = EnumSet::new();
|
|
|
|
assert_eq!(e.len(), 0);
|
|
|
|
e.insert(A);
|
|
|
|
e.insert(B);
|
|
|
|
e.insert(C);
|
|
|
|
assert_eq!(e.len(), 3);
|
|
|
|
e.remove(&A);
|
|
|
|
assert_eq!(e.len(), 2);
|
|
|
|
e.clear();
|
|
|
|
assert_eq!(e.len(), 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
|
|
// intersect
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_two_empties_do_not_intersect() {
|
|
|
|
let e1: EnumSet<Foo> = EnumSet::new();
|
|
|
|
let e2: EnumSet<Foo> = EnumSet::new();
|
|
|
|
assert!(e1.is_disjoint(&e2));
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_empty_does_not_intersect_with_full() {
|
|
|
|
let e1: EnumSet<Foo> = EnumSet::new();
|
|
|
|
|
|
|
|
let mut e2: EnumSet<Foo> = EnumSet::new();
|
|
|
|
e2.insert(A);
|
|
|
|
e2.insert(B);
|
|
|
|
e2.insert(C);
|
|
|
|
|
|
|
|
assert!(e1.is_disjoint(&e2));
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_disjoint_intersects() {
|
|
|
|
let mut e1: EnumSet<Foo> = EnumSet::new();
|
|
|
|
e1.insert(A);
|
|
|
|
|
|
|
|
let mut e2: EnumSet<Foo> = EnumSet::new();
|
|
|
|
e2.insert(B);
|
|
|
|
|
|
|
|
assert!(e1.is_disjoint(&e2));
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_overlapping_intersects() {
|
|
|
|
let mut e1: EnumSet<Foo> = EnumSet::new();
|
|
|
|
e1.insert(A);
|
|
|
|
|
|
|
|
let mut e2: EnumSet<Foo> = EnumSet::new();
|
|
|
|
e2.insert(A);
|
|
|
|
e2.insert(B);
|
|
|
|
|
|
|
|
assert!(!e1.is_disjoint(&e2));
|
|
|
|
}
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
|
|
// contains and contains_elem
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_superset() {
|
|
|
|
let mut e1: EnumSet<Foo> = EnumSet::new();
|
|
|
|
e1.insert(A);
|
|
|
|
|
|
|
|
let mut e2: EnumSet<Foo> = EnumSet::new();
|
|
|
|
e2.insert(A);
|
|
|
|
e2.insert(B);
|
|
|
|
|
|
|
|
let mut e3: EnumSet<Foo> = EnumSet::new();
|
|
|
|
e3.insert(C);
|
|
|
|
|
|
|
|
assert!(e1.is_subset(&e2));
|
|
|
|
assert!(e2.is_superset(&e1));
|
|
|
|
assert!(!e3.is_superset(&e2));
|
|
|
|
assert!(!e2.is_superset(&e3))
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_contains() {
|
|
|
|
let mut e1: EnumSet<Foo> = EnumSet::new();
|
|
|
|
e1.insert(A);
|
|
|
|
assert!(e1.contains(&A));
|
|
|
|
assert!(!e1.contains(&B));
|
|
|
|
assert!(!e1.contains(&C));
|
|
|
|
|
|
|
|
e1.insert(A);
|
|
|
|
e1.insert(B);
|
|
|
|
assert!(e1.contains(&A));
|
|
|
|
assert!(e1.contains(&B));
|
|
|
|
assert!(!e1.contains(&C));
|
|
|
|
}
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
|
|
// iter
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_iterator() {
|
|
|
|
let mut e1: EnumSet<Foo> = EnumSet::new();
|
|
|
|
|
2015-03-11 19:28:58 -05:00
|
|
|
let elems: Vec<Foo> = e1.iter().collect();
|
2015-03-10 23:58:16 -05:00
|
|
|
assert!(elems.is_empty());
|
|
|
|
|
|
|
|
e1.insert(A);
|
2015-03-11 19:28:58 -05:00
|
|
|
let elems: Vec<_> = e1.iter().collect();
|
2015-03-10 19:59:23 -05:00
|
|
|
assert_eq!(elems, [A]);
|
2015-03-10 23:58:16 -05:00
|
|
|
|
|
|
|
e1.insert(C);
|
2015-03-11 19:28:58 -05:00
|
|
|
let elems: Vec<_> = e1.iter().collect();
|
2015-03-10 19:59:23 -05:00
|
|
|
assert_eq!(elems, [A,C]);
|
2015-03-10 23:58:16 -05:00
|
|
|
|
|
|
|
e1.insert(C);
|
2015-03-11 19:28:58 -05:00
|
|
|
let elems: Vec<_> = e1.iter().collect();
|
2015-03-10 19:59:23 -05:00
|
|
|
assert_eq!(elems, [A,C]);
|
2015-03-10 23:58:16 -05:00
|
|
|
|
|
|
|
e1.insert(B);
|
2015-03-11 19:28:58 -05:00
|
|
|
let elems: Vec<_> = e1.iter().collect();
|
2015-03-10 19:59:23 -05:00
|
|
|
assert_eq!(elems, [A,B,C]);
|
2015-03-10 23:58:16 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
|
|
// operators
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_operators() {
|
|
|
|
let mut e1: EnumSet<Foo> = EnumSet::new();
|
|
|
|
e1.insert(A);
|
|
|
|
e1.insert(C);
|
|
|
|
|
|
|
|
let mut e2: EnumSet<Foo> = EnumSet::new();
|
|
|
|
e2.insert(B);
|
|
|
|
e2.insert(C);
|
|
|
|
|
|
|
|
let e_union = e1 | e2;
|
2015-03-11 19:28:58 -05:00
|
|
|
let elems: Vec<_> = e_union.iter().collect();
|
2015-03-10 19:59:23 -05:00
|
|
|
assert_eq!(elems, [A,B,C]);
|
2015-03-10 23:58:16 -05:00
|
|
|
|
|
|
|
let e_intersection = e1 & e2;
|
2015-03-11 19:28:58 -05:00
|
|
|
let elems: Vec<_> = e_intersection.iter().collect();
|
2015-03-10 19:59:23 -05:00
|
|
|
assert_eq!(elems, [C]);
|
2015-03-10 23:58:16 -05:00
|
|
|
|
|
|
|
// Another way to express intersection
|
|
|
|
let e_intersection = e1 - (e1 - e2);
|
2015-03-11 19:28:58 -05:00
|
|
|
let elems: Vec<_> = e_intersection.iter().collect();
|
2015-03-10 19:59:23 -05:00
|
|
|
assert_eq!(elems, [C]);
|
2015-03-10 23:58:16 -05:00
|
|
|
|
|
|
|
let e_subtract = e1 - e2;
|
2015-03-11 19:28:58 -05:00
|
|
|
let elems: Vec<_> = e_subtract.iter().collect();
|
2015-03-10 19:59:23 -05:00
|
|
|
assert_eq!(elems, [A]);
|
2015-03-10 23:58:16 -05:00
|
|
|
|
|
|
|
// Bitwise XOR of two sets, aka symmetric difference
|
|
|
|
let e_symmetric_diff = e1 ^ e2;
|
2015-03-11 19:28:58 -05:00
|
|
|
let elems: Vec<_> = e_symmetric_diff.iter().collect();
|
2015-03-10 19:59:23 -05:00
|
|
|
assert_eq!(elems, [A,B]);
|
2015-03-10 23:58:16 -05:00
|
|
|
|
|
|
|
// Another way to express symmetric difference
|
|
|
|
let e_symmetric_diff = (e1 - e2) | (e2 - e1);
|
2015-03-11 19:28:58 -05:00
|
|
|
let elems: Vec<_> = e_symmetric_diff.iter().collect();
|
2015-03-10 19:59:23 -05:00
|
|
|
assert_eq!(elems, [A,B]);
|
2015-03-10 23:58:16 -05:00
|
|
|
|
|
|
|
// Yet another way to express symmetric difference
|
|
|
|
let e_symmetric_diff = (e1 | e2) - (e1 & e2);
|
2015-03-11 19:28:58 -05:00
|
|
|
let elems: Vec<_> = e_symmetric_diff.iter().collect();
|
2015-03-10 19:59:23 -05:00
|
|
|
assert_eq!(elems, [A,B]);
|
2015-03-10 23:58:16 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
#[should_panic]
|
|
|
|
fn test_overflow() {
|
|
|
|
#[allow(dead_code)]
|
2015-03-30 08:40:52 -05:00
|
|
|
#[derive(Copy, Clone)]
|
2015-03-10 23:58:16 -05:00
|
|
|
#[repr(usize)]
|
|
|
|
enum Bar {
|
|
|
|
V00, V01, V02, V03, V04, V05, V06, V07, V08, V09,
|
|
|
|
V10, V11, V12, V13, V14, V15, V16, V17, V18, V19,
|
|
|
|
V20, V21, V22, V23, V24, V25, V26, V27, V28, V29,
|
|
|
|
V30, V31, V32, V33, V34, V35, V36, V37, V38, V39,
|
|
|
|
V40, V41, V42, V43, V44, V45, V46, V47, V48, V49,
|
|
|
|
V50, V51, V52, V53, V54, V55, V56, V57, V58, V59,
|
|
|
|
V60, V61, V62, V63, V64, V65, V66, V67, V68, V69,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl CLike for Bar {
|
|
|
|
fn to_usize(&self) -> usize {
|
|
|
|
*self as usize
|
|
|
|
}
|
|
|
|
|
|
|
|
fn from_usize(v: usize) -> Bar {
|
|
|
|
unsafe { mem::transmute(v) }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
let mut set = EnumSet::new();
|
|
|
|
set.insert(Bar::V64);
|
|
|
|
}
|
2015-06-03 05:38:42 -05:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_extend_ref() {
|
|
|
|
let mut a = EnumSet::new();
|
|
|
|
a.insert(A);
|
|
|
|
|
|
|
|
a.extend(&[A, C]);
|
|
|
|
|
|
|
|
assert_eq!(a.len(), 2);
|
|
|
|
assert!(a.contains(&A));
|
|
|
|
assert!(a.contains(&C));
|
|
|
|
|
|
|
|
let mut b = EnumSet::new();
|
|
|
|
b.insert(B);
|
|
|
|
|
|
|
|
a.extend(&b);
|
|
|
|
|
|
|
|
assert_eq!(a.len(), 3);
|
|
|
|
assert!(a.contains(&A));
|
|
|
|
assert!(a.contains(&B));
|
|
|
|
assert!(a.contains(&C));
|
|
|
|
}
|