--- /dev/null
+// 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::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;
+}
+
+fn bit<E:CLike>(e: E) -> uint {
+ 1 << e.to_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
+ }
+
+ /// Returns an iterator over an EnumSet
+ pub fn iter(&self) -> EnumSetIterator<E> {
+ EnumSetIterator::new(self.bits)
+ }
+}
+
+impl<E:CLike> Sub<EnumSet<E>, EnumSet<E>> for EnumSet<E> {
+ fn sub(&self, e: &EnumSet<E>) -> EnumSet<E> {
+ EnumSet {bits: self.bits & !e.bits}
+ }
+}
+
+impl<E:CLike> BitOr<EnumSet<E>, EnumSet<E>> for EnumSet<E> {
+ fn bitor(&self, e: &EnumSet<E>) -> EnumSet<E> {
+ EnumSet {bits: self.bits | e.bits}
+ }
+}
+
+impl<E:CLike> BitAnd<EnumSet<E>, EnumSet<E>> for EnumSet<E> {
+ fn bitand(&self, e: &EnumSet<E>) -> EnumSet<E> {
+ EnumSet {bits: self.bits & e.bits}
+ }
+}
+
+/// An iterator over an EnumSet
+pub struct EnumSetIterator<E> {
+ priv index: uint,
+ priv bits: uint,
+}
+
+impl<E:CLike> EnumSetIterator<E> {
+ fn new(bits: uint) -> EnumSetIterator<E> {
+ EnumSetIterator { index: 0, bits: bits }
+ }
+}
+
+impl<E:CLike> Iterator<E> for EnumSetIterator<E> {
+ fn next(&mut self) -> Option<E> {
+ if (self.bits == 0) {
+ return None;
+ }
+
+ while (self.bits & 1) == 0 {
+ self.index += 1;
+ self.bits >>= 1;
+ }
+ let elem = CLike::from_uint(self.index);
+ self.index += 1;
+ self.bits >>= 1;
+ Some(elem)
+ }
+
+ fn size_hint(&self) -> (uint, Option<uint>) {
+ let exact = self.bits.population_count();
+ (exact, Some(exact))
+ }
+}
+
+#[cfg(test)]
+mod test {
+
+ use std::cast;
+
+ use enum_set::*;
+
+ #[deriving(Eq)]
+ enum Foo {
+ A, B, C
+ }
+
+ impl CLike for Foo {
+ pub fn to_uint(&self) -> uint {
+ *self as uint
+ }
+
+ pub fn from_uint(v: uint) -> Foo {
+ unsafe { cast::transmute(v) }
+ }
+ }
+
+ #[test]
+ fn test_empty() {
+ let e: EnumSet<Foo> = EnumSet::empty();
+ assert!(e.is_empty());
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ // intersect
+
+ #[test]
+ fn test_two_empties_do_not_intersect() {
+ let e1: EnumSet<Foo> = EnumSet::empty();
+ let e2: EnumSet<Foo> = EnumSet::empty();
+ assert!(!e1.intersects(e2));
+ }
+
+ #[test]
+ fn test_empty_does_not_intersect_with_full() {
+ let e1: EnumSet<Foo> = EnumSet::empty();
+
+ let mut e2: EnumSet<Foo> = EnumSet::empty();
+ e2.add(A);
+ e2.add(B);
+ e2.add(C);
+
+ assert!(!e1.intersects(e2));
+ }
+
+ #[test]
+ fn test_disjoint_intersects() {
+ let mut e1: EnumSet<Foo> = EnumSet::empty();
+ e1.add(A);
+
+ let mut e2: EnumSet<Foo> = EnumSet::empty();
+ e2.add(B);
+
+ assert!(!e1.intersects(e2));
+ }
+
+ #[test]
+ fn test_overlapping_intersects() {
+ let mut e1: EnumSet<Foo> = EnumSet::empty();
+ e1.add(A);
+
+ let mut e2: EnumSet<Foo> = EnumSet::empty();
+ e2.add(A);
+ e2.add(B);
+
+ assert!(e1.intersects(e2));
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ // contains and contains_elem
+
+ #[test]
+ fn test_contains() {
+ let mut e1: EnumSet<Foo> = EnumSet::empty();
+ e1.add(A);
+
+ let mut e2: EnumSet<Foo> = EnumSet::empty();
+ e2.add(A);
+ e2.add(B);
+
+ assert!(!e1.contains(e2));
+ assert!(e2.contains(e1));
+ }
+
+ #[test]
+ fn test_contains_elem() {
+ let mut e1: EnumSet<Foo> = EnumSet::empty();
+ e1.add(A);
+ assert!(e1.contains_elem(A));
+ assert!(!e1.contains_elem(B));
+ assert!(!e1.contains_elem(C));
+
+ e1.add(A);
+ e1.add(B);
+ assert!(e1.contains_elem(A));
+ assert!(e1.contains_elem(B));
+ assert!(!e1.contains_elem(C));
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ // iter
+
+ #[test]
+ fn test_iterator() {
+ let mut e1: EnumSet<Foo> = EnumSet::empty();
+
+ let elems: ~[Foo] = e1.iter().collect();
+ assert_eq!(~[], elems)
+
+ e1.add(A);
+ let elems: ~[Foo] = e1.iter().collect();
+ assert_eq!(~[A], elems)
+
+ e1.add(C);
+ let elems: ~[Foo] = e1.iter().collect();
+ assert_eq!(~[A,C], elems)
+
+ e1.add(C);
+ let elems: ~[Foo] = e1.iter().collect();
+ assert_eq!(~[A,C], elems)
+
+ e1.add(B);
+ let elems: ~[Foo] = e1.iter().collect();
+ assert_eq!(~[A,B,C], elems)
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ // operators
+
+ #[test]
+ fn test_operators() {
+ let mut e1: EnumSet<Foo> = EnumSet::empty();
+ e1.add(A);
+ e1.add(C);
+
+ let mut e2: EnumSet<Foo> = EnumSet::empty();
+ e2.add(B);
+ e2.add(C);
+
+ let e_union = e1 | e2;
+ let elems: ~[Foo] = e_union.iter().collect();
+ assert_eq!(~[A,B,C], elems)
+
+ let e_intersection = e1 & e2;
+ let elems: ~[Foo] = e_intersection.iter().collect();
+ assert_eq!(~[C], elems)
+
+ let e_subtract = e1 - e2;
+ let elems: ~[Foo] = e_subtract.iter().collect();
+ assert_eq!(~[A], elems)
+ }
+}
pub mod base64;
pub mod rl;
pub mod workcache;
+pub mod enum_set;
#[path="num/bigint.rs"]
pub mod bigint;
#[path="num/rational.rs"]
}
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');
{
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);
}
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;
use syntax::opt_vec;
use syntax::abi::AbiSet;
use syntax;
+use extra::enum_set::{EnumSet, CLike};
pub static INITIAL_DISCRIMINANT_VALUE: uint = 0;
// 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.
BoundFreeze => TC_MUTABLE,
BoundSized => TC_NONE, // don't care if interior is sized
};
- true
- };
+ }
st + mt + bt
}
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),
// 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;
pub mod util {
pub mod common;
pub mod ppaux;
- pub mod enum_set;
}
pub mod lib {
+++ /dev/null
-// 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::iterator::Iterator;
-
-#[deriving(Clone, Eq, IterBytes, ToStr)]
-pub struct EnumSet<E> {
- // We must maintain the invariant that no bits are set
- // for which no variant exists
- priv bits: uint
-}
-
-pub trait CLike {
- pub fn to_uint(&self) -> uint;
- pub fn from_uint(uint) -> Self;
-}
-
-fn bit<E:CLike>(e: E) -> uint {
- 1 << e.to_uint()
-}
-
-impl<E:CLike> EnumSet<E> {
- pub fn empty() -> EnumSet<E> {
- EnumSet {bits: 0}
- }
-
- pub fn is_empty(&self) -> bool {
- self.bits == 0
- }
-
- pub fn intersects(&self, e: EnumSet<E>) -> bool {
- (self.bits & e.bits) != 0
- }
-
- pub fn intersection(&self, e: EnumSet<E>) -> EnumSet<E> {
- EnumSet {bits: self.bits & e.bits}
- }
-
- pub fn contains(&self, e: EnumSet<E>) -> bool {
- (self.bits & e.bits) == e.bits
- }
-
- pub fn union(&self, e: EnumSet<E>) -> EnumSet<E> {
- EnumSet {bits: self.bits | e.bits}
- }
-
- pub fn add(&mut self, e: E) {
- self.bits |= bit(e);
- }
-
- 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;
- }
-
- pub fn iter(&self) -> EnumSetIterator<E> {
- EnumSetIterator::new(self.bits)
- }
-}
-
-impl<E:CLike> Sub<EnumSet<E>, EnumSet<E>> for EnumSet<E> {
- fn sub(&self, e: &EnumSet<E>) -> EnumSet<E> {
- EnumSet {bits: self.bits & !e.bits}
- }
-}
-
-impl<E:CLike> BitOr<EnumSet<E>, EnumSet<E>> for EnumSet<E> {
- fn bitor(&self, e: &EnumSet<E>) -> EnumSet<E> {
- EnumSet {bits: self.bits | e.bits}
- }
-}
-
-impl<E:CLike> BitAnd<EnumSet<E>, EnumSet<E>> for EnumSet<E> {
- fn bitand(&self, e: &EnumSet<E>) -> EnumSet<E> {
- EnumSet {bits: self.bits & e.bits}
- }
-}
-
-pub struct EnumSetIterator<E> {
- priv index: uint,
- priv bits: uint,
-}
-
-impl<E:CLike> EnumSetIterator<E> {
- fn new(bits: uint) -> EnumSetIterator<E> {
- EnumSetIterator { index: 0, bits: bits }
- }
-}
-
-impl<E:CLike> Iterator<E> for EnumSetIterator<E> {
- fn next(&mut self) -> Option<E> {
- if (self.bits == 0) {
- return None;
- }
-
- while (self.bits & 1) == 0 {
- self.index += 1;
- self.bits >>= 1;
- }
- let elem = CLike::from_uint(self.index);
- self.index += 1;
- self.bits >>= 1;
- Some(elem)
- }
-
- fn size_hint(&self) -> (uint, Option<uint>) {
- let exact = self.bits.population_count();
- (exact, Some(exact))
- }
-}
-
-#[cfg(test)]
-mod test {
-
- use std::cast;
-
- use util::enum_set::*;
-
- #[deriving(Eq)]
- enum Foo {
- A, B, C
- }
-
- impl CLike for Foo {
- pub fn to_uint(&self) -> uint {
- *self as uint
- }
-
- pub fn from_uint(v: uint) -> Foo {
- unsafe { cast::transmute(v) }
- }
- }
-
- #[test]
- fn test_empty() {
- let e: EnumSet<Foo> = EnumSet::empty();
- assert!(e.is_empty());
- }
-
- ///////////////////////////////////////////////////////////////////////////
- // intersect
-
- #[test]
- fn test_two_empties_do_not_intersect() {
- let e1: EnumSet<Foo> = EnumSet::empty();
- let e2: EnumSet<Foo> = EnumSet::empty();
- assert!(!e1.intersects(e2));
- }
-
- #[test]
- fn test_empty_does_not_intersect_with_full() {
- let e1: EnumSet<Foo> = EnumSet::empty();
-
- let mut e2: EnumSet<Foo> = EnumSet::empty();
- e2.add(A);
- e2.add(B);
- e2.add(C);
-
- assert!(!e1.intersects(e2));
- }
-
- #[test]
- fn test_disjoint_intersects() {
- let mut e1: EnumSet<Foo> = EnumSet::empty();
- e1.add(A);
-
- let mut e2: EnumSet<Foo> = EnumSet::empty();
- e2.add(B);
-
- assert!(!e1.intersects(e2));
- }
-
- #[test]
- fn test_overlapping_intersects() {
- let mut e1: EnumSet<Foo> = EnumSet::empty();
- e1.add(A);
-
- let mut e2: EnumSet<Foo> = EnumSet::empty();
- e2.add(A);
- e2.add(B);
-
- assert!(e1.intersects(e2));
- }
-
- ///////////////////////////////////////////////////////////////////////////
- // contains and contains_elem
-
- #[test]
- fn test_contains() {
- let mut e1: EnumSet<Foo> = EnumSet::empty();
- e1.add(A);
-
- let mut e2: EnumSet<Foo> = EnumSet::empty();
- e2.add(A);
- e2.add(B);
-
- assert!(!e1.contains(e2));
- assert!(e2.contains(e1));
- }
-
- #[test]
- fn test_contains_elem() {
- let mut e1: EnumSet<Foo> = EnumSet::empty();
- e1.add(A);
- assert!(e1.contains_elem(A));
- assert!(!e1.contains_elem(B));
- assert!(!e1.contains_elem(C));
-
- e1.add(A);
- e1.add(B);
- assert!(e1.contains_elem(A));
- assert!(e1.contains_elem(B));
- assert!(!e1.contains_elem(C));
- }
-
- ///////////////////////////////////////////////////////////////////////////
- // iter / each
-
- #[test]
- fn test_iterator() {
- let mut e1: EnumSet<Foo> = EnumSet::empty();
-
- let elems: ~[Foo] = e1.iter().collect();
- assert_eq!(~[], elems)
-
- e1.add(A);
- let elems: ~[Foo] = e1.iter().collect();
- assert_eq!(~[A], elems)
-
- e1.add(C);
- let elems: ~[Foo] = e1.iter().collect();
- assert_eq!(~[A,C], elems)
-
- e1.add(C);
- let elems: ~[Foo] = e1.iter().collect();
- assert_eq!(~[A,C], elems)
-
- e1.add(B);
- let elems: ~[Foo] = e1.iter().collect();
- 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
-
- #[test]
- fn test_operators() {
- let mut e1: EnumSet<Foo> = EnumSet::empty();
- e1.add(A);
- e1.add(C);
-
- let mut e2: EnumSet<Foo> = EnumSet::empty();
- e2.add(B);
- e2.add(C);
-
- let e_union = e1 | e2;
- let elems: ~[Foo] = e_union.iter().collect();
- assert_eq!(~[A,B,C], elems)
-
- let e_intersection = e1 & e2;
- let elems: ~[Foo] = e_intersection.iter().collect();
- assert_eq!(~[C], elems)
-
- let e_subtract = e1 - e2;
- let elems: ~[Foo] = e_subtract.iter().collect();
- assert_eq!(~[A], elems)
- }
-}
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));
}
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("+")
}
}