blob: 972361326d7bb33af99e99d0a34b49ff8a4ccc70 [file] [log] [blame]
// 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.
use std::mem;
use collections::enum_set::{CLike, EnumSet};
use self::Foo::*;
#[derive(Copy, Clone, PartialEq, Debug)]
#[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();
let elems: Vec<Foo> = e1.iter().collect();
assert!(elems.is_empty());
e1.insert(A);
let elems: Vec<_> = e1.iter().collect();
assert_eq!(elems, [A]);
e1.insert(C);
let elems: Vec<_> = e1.iter().collect();
assert_eq!(elems, [A, C]);
e1.insert(C);
let elems: Vec<_> = e1.iter().collect();
assert_eq!(elems, [A, C]);
e1.insert(B);
let elems: Vec<_> = e1.iter().collect();
assert_eq!(elems, [A, B, C]);
}
///////////////////////////////////////////////////////////////////////////
// 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;
let elems: Vec<_> = e_union.iter().collect();
assert_eq!(elems, [A, B, C]);
let e_intersection = e1 & e2;
let elems: Vec<_> = e_intersection.iter().collect();
assert_eq!(elems, [C]);
// Another way to express intersection
let e_intersection = e1 - (e1 - e2);
let elems: Vec<_> = e_intersection.iter().collect();
assert_eq!(elems, [C]);
let e_subtract = e1 - e2;
let elems: Vec<_> = e_subtract.iter().collect();
assert_eq!(elems, [A]);
// Bitwise XOR of two sets, aka symmetric difference
let e_symmetric_diff = e1 ^ e2;
let elems: Vec<_> = e_symmetric_diff.iter().collect();
assert_eq!(elems, [A, B]);
// Another way to express symmetric difference
let e_symmetric_diff = (e1 - e2) | (e2 - e1);
let elems: Vec<_> = e_symmetric_diff.iter().collect();
assert_eq!(elems, [A, B]);
// Yet another way to express symmetric difference
let e_symmetric_diff = (e1 | e2) - (e1 & e2);
let elems: Vec<_> = e_symmetric_diff.iter().collect();
assert_eq!(elems, [A, B]);
}
#[test]
#[should_panic]
fn test_overflow() {
#[allow(dead_code)]
#[derive(Copy, Clone)]
#[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);
}
#[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));
}