Test case:
extern crate collections;
use collections::enum_set::{EnumSet, CLike};
use std::cast;
#[repr(uint)]
enum Foo {
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 Foo {
fn to_uint(&self) -> uint {
*self as uint
}
fn from_uint(v: uint) -> Foo {
unsafe { cast::transmute(v) }
}
}
fn main() {
let mut set: EnumSet<Foo> = EnumSet::empty();
set.add(V63);
set.add(V64);
set.add(V65);
println!("{:?}", set.iter().collect::<~[Foo]>())
}
Expected result, in decreasing order of preference: ~[V63, V64, V65], compile-time failure, or run-time failure.
Actual result with rustc eea4909 on a 64 bit system: ~[V00, V01, V63]
Use case: Servo currently handles CSS declarations in order, later ones overwriting earlier ones. I’d like instead to process declarations in reverse order, and skip those for properties for which we already have a value. "Already have a value" would be stored in an EnumSet with one variant for every CSS property. There are a few hundreds of them. (The enum is automatically generated.) (Values can not be Options, because they’re initialized to the inherited or initial value rather than None.)
Possible fixes:
- To at least avoid silently corrupting data, have the
bit function assert (non-disablable) that e.to_uint() < (size_of<uint>() * 8)
- Do 1., and also add a
BigEnumSet type that uses Vec<uint> or ~[uint] internally for storage rather than just a single uint.
- Change
EnumSet to decide at run-time to use ~[uint] or a single uint for storage, like collections::bitv::Bitv does.
- Like 3., but decide at compile-time what kind of storage to use. (Since the generic
EnumSet is being monomorphized anyway.) I don’t know if this is possible.
3 or 4 might need the CLike trait to gain a max_value associated function (or something), which would ideally be based on introspection rather than leaving the counting to the user.
Test case:
Expected result, in decreasing order of preference:
~[V63, V64, V65], compile-time failure, or run-time failure.Actual result with rustc eea4909 on a 64 bit system:
~[V00, V01, V63]Use case: Servo currently handles CSS declarations in order, later ones overwriting earlier ones. I’d like instead to process declarations in reverse order, and skip those for properties for which we already have a value. "Already have a value" would be stored in an EnumSet with one variant for every CSS property. There are a few hundreds of them. (The enum is automatically generated.) (Values can not be
Options, because they’re initialized to the inherited or initial value rather thanNone.)Possible fixes:
bitfunction assert (non-disablable) thate.to_uint() < (size_of<uint>() * 8)BigEnumSettype that usesVec<uint>or~[uint]internally for storage rather than just a singleuint.EnumSetto decide at run-time to use~[uint]or a singleuintfor storage, likecollections::bitv::Bitvdoes.EnumSetis being monomorphized anyway.) I don’t know if this is possible.3 or 4 might need the
CLiketrait to gain amax_valueassociated function (or something), which would ideally be based on introspection rather than leaving the counting to the user.