@@ -43,7 +43,27 @@ impl<E:CLike+fmt::Show> fmt::Show for EnumSet<E> {
43
43
}
44
44
}
45
45
46
- /// An interface for casting C-like enum to uint and back.
46
+ /**
47
+ An interface for casting C-like enum to uint and back.
48
+ A typically implementation is as below.
49
+
50
+ ```{rust,ignore}
51
+ #[repr(uint)]
52
+ enum Foo {
53
+ A, B, C
54
+ }
55
+
56
+ impl CLike for Foo {
57
+ fn to_uint(&self) -> uint {
58
+ *self as uint
59
+ }
60
+
61
+ fn from_uint(v: uint) -> Foo {
62
+ unsafe { mem::transmute(v) }
63
+ }
64
+ }
65
+ ```
66
+ */
47
67
pub trait CLike {
48
68
/// Converts a C-like enum to a `uint`.
49
69
fn to_uint ( & self ) -> uint ;
@@ -52,7 +72,11 @@ pub trait CLike {
52
72
}
53
73
54
74
fn bit < E : CLike > ( e : & E ) -> uint {
55
- 1 << e. to_uint ( )
75
+ use core:: uint;
76
+ let value = e. to_uint ( ) ;
77
+ assert ! ( value < uint:: BITS ,
78
+ "EnumSet only supports up to {} variants." , uint:: BITS - 1 ) ;
79
+ 1 << value
56
80
}
57
81
58
82
impl < E : CLike > EnumSet < E > {
@@ -378,4 +402,31 @@ mod test {
378
402
let elems = e_subtract. iter ( ) . collect ( ) ;
379
403
assert_eq ! ( vec![ A ] , elems)
380
404
}
405
+
406
+ #[ test]
407
+ #[ should_fail]
408
+ fn test_overflow ( ) {
409
+ #[ allow( dead_code) ]
410
+ #[ repr( uint) ]
411
+ enum Bar {
412
+ V00 , V01 , V02 , V03 , V04 , V05 , V06 , V07 , V08 , V09 ,
413
+ V10 , V11 , V12 , V13 , V14 , V15 , V16 , V17 , V18 , V19 ,
414
+ V20 , V21 , V22 , V23 , V24 , V25 , V26 , V27 , V28 , V29 ,
415
+ V30 , V31 , V32 , V33 , V34 , V35 , V36 , V37 , V38 , V39 ,
416
+ V40 , V41 , V42 , V43 , V44 , V45 , V46 , V47 , V48 , V49 ,
417
+ V50 , V51 , V52 , V53 , V54 , V55 , V56 , V57 , V58 , V59 ,
418
+ V60 , V61 , V62 , V63 , V64 , V65 , V66 , V67 , V68 , V69 ,
419
+ }
420
+ impl CLike for Bar {
421
+ fn to_uint ( & self ) -> uint {
422
+ * self as uint
423
+ }
424
+
425
+ fn from_uint ( v : uint ) -> Bar {
426
+ unsafe { mem:: transmute ( v) }
427
+ }
428
+ }
429
+ let mut set = EnumSet :: empty ( ) ;
430
+ set. add ( V64 ) ;
431
+ }
381
432
}
0 commit comments