Move EnumSet into libextra
This commit is contained in:
parent
bbda3fa938
commit
a76943be47
@ -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
|
||||
|
@ -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"]
|
||||
|
@ -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');
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -96,7 +96,6 @@ pub mod driver;
|
||||
pub mod util {
|
||||
pub mod common;
|
||||
pub mod ppaux;
|
||||
pub mod enum_set;
|
||||
}
|
||||
|
||||
pub mod lib {
|
||||
|
@ -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("+")
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user