1 use core::convert::TryInto;
2 use core::fmt::{Debug};
3 use core::hash::{Hash};
6 /// A trait marking valid underlying bitset storage types and providing the
7 /// operations `EnumSet` and related types use.
8 pub trait EnumSetTypeRepr :
9 // Basic traits used to derive traits
15 // Operations used by enumset
16 BitAnd<Output = Self> +
17 BitOr<Output = Self> +
18 BitXor<Output = Self> +
23 fn is_empty(&self) -> bool;
26 fn add_bit(&mut self, bit: u32);
27 fn remove_bit(&mut self, bit: u32);
28 fn has_bit(&self, bit: u32) -> bool;
30 fn count_ones(&self) -> u32;
31 fn count_remaining_ones(&self, cursor: u32) -> usize;
32 fn leading_zeros(&self) -> u32;
33 fn trailing_zeros(&self) -> u32;
35 fn and_not(&self, other: Self) -> Self;
37 fn from_u8(v: u8) -> Self;
38 fn from_u16(v: u16) -> Self;
39 fn from_u32(v: u32) -> Self;
40 fn from_u64(v: u64) -> Self;
41 fn from_u128(v: u128) -> Self;
42 fn from_usize(v: usize) -> Self;
44 fn to_u8(&self) -> u8;
45 fn to_u16(&self) -> u16;
46 fn to_u32(&self) -> u32;
47 fn to_u64(&self) -> u64;
48 fn to_u128(&self) -> u128;
49 fn to_usize(&self) -> usize;
51 fn from_u8_opt(v: u8) -> Option<Self>;
52 fn from_u16_opt(v: u16) -> Option<Self>;
53 fn from_u32_opt(v: u32) -> Option<Self>;
54 fn from_u64_opt(v: u64) -> Option<Self>;
55 fn from_u128_opt(v: u128) -> Option<Self>;
56 fn from_usize_opt(v: usize) -> Option<Self>;
58 fn to_u8_opt(&self) -> Option<u8>;
59 fn to_u16_opt(&self) -> Option<u16>;
60 fn to_u32_opt(&self) -> Option<u32>;
61 fn to_u64_opt(&self) -> Option<u64>;
62 fn to_u128_opt(&self) -> Option<u128>;
63 fn to_usize_opt(&self) -> Option<usize>;
66 ($name:ty, $width:expr) => {
67 impl EnumSetTypeRepr for $name {
68 const WIDTH: u32 = $width;
70 fn is_empty(&self) -> bool { *self == 0 }
71 fn empty() -> Self { 0 }
73 fn add_bit(&mut self, bit: u32) {
74 *self |= 1 << bit as $name;
76 fn remove_bit(&mut self, bit: u32) {
77 *self &= !(1 << bit as $name);
79 fn has_bit(&self, bit: u32) -> bool {
80 (self & (1 << bit as $name)) != 0
83 fn count_ones(&self) -> u32 { (*self).count_ones() }
84 fn leading_zeros(&self) -> u32 { (*self).leading_zeros() }
85 fn trailing_zeros(&self) -> u32 { (*self).trailing_zeros() }
87 fn and_not(&self, other: Self) -> Self { (*self) & !other }
89 fn count_remaining_ones(&self, cursor: u32) -> usize {
91 !((1 as $name).checked_shl(cursor).unwrap_or(0).wrapping_sub(1));
92 (*self & left_mask).count_ones() as usize
95 fn from_u8(v: u8) -> Self { v as $name }
96 fn from_u16(v: u16) -> Self { v as $name }
97 fn from_u32(v: u32) -> Self { v as $name }
98 fn from_u64(v: u64) -> Self { v as $name }
99 fn from_u128(v: u128) -> Self { v as $name }
100 fn from_usize(v: usize) -> Self { v as $name }
102 fn to_u8(&self) -> u8 { (*self) as u8 }
103 fn to_u16(&self) -> u16 { (*self) as u16 }
104 fn to_u32(&self) -> u32 { (*self) as u32 }
105 fn to_u64(&self) -> u64 { (*self) as u64 }
106 fn to_u128(&self) -> u128 { (*self) as u128 }
107 fn to_usize(&self) -> usize { (*self) as usize }
109 fn from_u8_opt(v: u8) -> Option<Self> { v.try_into().ok() }
110 fn from_u16_opt(v: u16) -> Option<Self> { v.try_into().ok() }
111 fn from_u32_opt(v: u32) -> Option<Self> { v.try_into().ok() }
112 fn from_u64_opt(v: u64) -> Option<Self> { v.try_into().ok() }
113 fn from_u128_opt(v: u128) -> Option<Self> { v.try_into().ok() }
114 fn from_usize_opt(v: usize) -> Option<Self> { v.try_into().ok() }
116 fn to_u8_opt(&self) -> Option<u8> { (*self).try_into().ok() }
117 fn to_u16_opt(&self) -> Option<u16> { (*self).try_into().ok() }
118 fn to_u32_opt(&self) -> Option<u32> { (*self).try_into().ok() }
119 fn to_u64_opt(&self) -> Option<u64> { (*self).try_into().ok() }
120 fn to_u128_opt(&self) -> Option<u128> { (*self).try_into().ok() }
121 fn to_usize_opt(&self) -> Option<usize> { (*self).try_into().ok() }