Move EnumSet into libextra

This commit is contained in:
Sangeun Kim 2013-07-26 13:53:29 +09:00
parent bbda3fa938
commit a76943be47
7 changed files with 30 additions and 66 deletions

View File

@ -11,14 +11,18 @@
use std::iterator::Iterator;
#[deriving(Clone, Eq, IterBytes, ToStr)]
/// A specialized Set implementation to use enum types.
pub struct EnumSet<E> {
// We must maintain the invariant that no bits are set
// for which no variant exists
priv bits: uint
}
/// An iterface for casting C-like enum to uint and back.
pub trait CLike {
/// Converts C-like enum to uint.
pub fn to_uint(&self) -> uint;
/// Converts uint to C-like enum.
pub fn from_uint(uint) -> Self;
}
@ -27,54 +31,47 @@ fn bit<E:CLike>(e: E) -> uint {
}
impl<E:CLike> EnumSet<E> {
/// Returns an empty EnumSet.
pub fn empty() -> EnumSet<E> {
EnumSet {bits: 0}
}
/// Returns true if an EnumSet is empty.
pub fn is_empty(&self) -> bool {
self.bits == 0
}
/// Returns true if an EnumSet contains any enum of a given EnumSet
pub fn intersects(&self, e: EnumSet<E>) -> bool {
(self.bits & e.bits) != 0
}
/// Returns an intersection of both EnumSets.
pub fn intersection(&self, e: EnumSet<E>) -> EnumSet<E> {
EnumSet {bits: self.bits & e.bits}
}
/// Returns true if a given EnumSet is included in an EnumSet.
pub fn contains(&self, e: EnumSet<E>) -> bool {
(self.bits & e.bits) == e.bits
}
/// Returns a union of both EnumSets.
pub fn union(&self, e: EnumSet<E>) -> EnumSet<E> {
EnumSet {bits: self.bits | e.bits}
}
/// Add an enum to an EnumSet
pub fn add(&mut self, e: E) {
self.bits |= bit(e);
}
/// Returns true if an EnumSet contains a given enum
pub fn contains_elem(&self, e: E) -> bool {
(self.bits & bit(e)) != 0
}
pub fn each(&self, f: &fn(E) -> bool) -> bool {
let mut bits = self.bits;
let mut index = 0;
while bits != 0 {
if (bits & 1) != 0 {
let e = CLike::from_uint(index);
if !f(e) {
return false;
}
}
index += 1;
bits >>= 1;
}
return true;
}
/// Returns an iterator over an EnumSet
pub fn iter(&self) -> EnumSetIterator<E> {
EnumSetIterator::new(self.bits)
}
@ -98,6 +95,7 @@ impl<E:CLike> BitAnd<EnumSet<E>, EnumSet<E>> for EnumSet<E> {
}
}
/// An iterator over an EnumSet
pub struct EnumSetIterator<E> {
priv index: uint,
priv bits: uint,
@ -136,7 +134,7 @@ mod test {
use std::cast;
use util::enum_set::*;
use enum_set::*;
#[deriving(Eq)]
enum Foo {
@ -236,7 +234,7 @@ mod test {
}
///////////////////////////////////////////////////////////////////////////
// iter / each
// iter
#[test]
fn test_iterator() {
@ -262,34 +260,6 @@ mod test {
assert_eq!(~[A,B,C], elems)
}
#[test]
fn test_each() {
let mut e1: EnumSet<Foo> = EnumSet::empty();
assert_eq!(~[], collect(e1))
e1.add(A);
assert_eq!(~[A], collect(e1))
e1.add(C);
assert_eq!(~[A,C], collect(e1))
e1.add(C);
assert_eq!(~[A,C], collect(e1))
e1.add(B);
assert_eq!(~[A,B,C], collect(e1))
}
fn collect(e: EnumSet<Foo>) -> ~[Foo] {
let mut elems = ~[];
e.each(|elem| {
elems.push(elem);
true
});
elems
}
///////////////////////////////////////////////////////////////////////////
// operators

View File

@ -91,6 +91,7 @@ pub mod par;
pub mod base64;
pub mod rl;
pub mod workcache;
pub mod enum_set;
#[path="num/bigint.rs"]
pub mod bigint;
#[path="num/rational.rs"]

View File

@ -413,15 +413,14 @@ fn enc_fn_sig(w: @io::Writer, cx: @ctxt, fsig: &ty::FnSig) {
}
fn enc_bounds(w: @io::Writer, cx: @ctxt, bs: &ty::ParamBounds) {
do bs.builtin_bounds.each |bound| {
for bound in bs.builtin_bounds.iter() {
match bound {
ty::BoundSend => w.write_char('S'),
ty::BoundFreeze => w.write_char('K'),
ty::BoundStatic => w.write_char('O'),
ty::BoundSized => w.write_char('Z'),
}
true
};
}
for &tp in bs.trait_bounds.iter() {
w.write_char('I');

View File

@ -338,12 +338,11 @@ pub fn check_builtin_bounds(cx: Context, ty: ty::t, bounds: ty::BuiltinBounds,
{
let kind = ty::type_contents(cx.tcx, ty);
let mut missing = ty::EmptyBuiltinBounds();
do bounds.each |bound| {
for bound in bounds.iter() {
if !kind.meets_bound(cx.tcx, bound) {
missing.add(bound);
}
true
};
}
if !missing.is_empty() {
any_missing(missing);
}

View File

@ -25,7 +25,6 @@ use util::ppaux::{note_and_explain_region, bound_region_ptr_to_str};
use util::ppaux::{trait_store_to_str, ty_to_str, vstore_to_str};
use util::ppaux::{Repr, UserString};
use util::common::{indenter};
use util::enum_set::{EnumSet, CLike};
use std::cast;
use std::cmp;
@ -48,6 +47,7 @@ use syntax::opt_vec::OptVec;
use syntax::opt_vec;
use syntax::abi::AbiSet;
use syntax;
use extra::enum_set::{EnumSet, CLike};
pub static INITIAL_DISCRIMINANT_VALUE: uint = 0;
@ -2287,7 +2287,7 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents {
// This is like with typarams below, but less "pessimistic" and also
// dependent on the trait store.
let mut bt = TC_NONE;
do (AllBuiltinBounds() - bounds).each |bound| {
for bound in (AllBuiltinBounds() - bounds).iter() {
bt = bt + match bound {
BoundStatic if bounds.contains_elem(BoundSend)
=> TC_NONE, // Send bound implies static bound.
@ -2296,8 +2296,7 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents {
BoundFreeze => TC_MUTABLE,
BoundSized => TC_NONE, // don't care if interior is sized
};
true
};
}
st + mt + bt
}
@ -2308,7 +2307,7 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents {
let _i = indenter();
let mut tc = TC_ALL;
do type_param_def.bounds.builtin_bounds.each |bound| {
for bound in type_param_def.bounds.builtin_bounds.iter() {
debug!("tc = %s, bound = %?", tc.to_str(), bound);
tc = tc - match bound {
BoundStatic => TypeContents::nonstatic(cx),
@ -2317,8 +2316,7 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents {
// The dynamic-size bit can be removed at pointer-level, etc.
BoundSized => TypeContents::dynamically_sized(cx),
};
true
};
}
debug!("result = %s", tc.to_str());
return tc;

View File

@ -96,7 +96,6 @@ pub mod driver;
pub mod util {
pub mod common;
pub mod ppaux;
pub mod enum_set;
}
pub mod lib {

View File

@ -589,15 +589,14 @@ impl Repr for ty::RegionSubsts {
impl Repr for ty::ParamBounds {
fn repr(&self, tcx: ctxt) -> ~str {
let mut res = ~[];
do self.builtin_bounds.each |b| {
for b in self.builtin_bounds.iter() {
res.push(match b {
ty::BoundStatic => ~"'static",
ty::BoundSend => ~"Send",
ty::BoundFreeze => ~"Freeze",
ty::BoundSized => ~"Sized",
});
true
};
}
for t in self.trait_bounds.iter() {
res.push(t.repr(tcx));
}
@ -833,10 +832,9 @@ impl UserString for ty::BuiltinBounds {
fn user_string(&self, tcx: ctxt) -> ~str {
if self.is_empty() { ~"<no-bounds>" } else {
let mut result = ~[];
do self.each |bb| {
for bb in self.iter() {
result.push(bb.user_string(tcx));
true
};
}
result.connect("+")
}
}