4 use std::collections::{HashSet, BTreeSet};
6 #[derive(EnumSetType, Debug)]
9 #[derive(EnumSetType, Debug)]
14 #[derive(EnumSetType, Debug)]
16 A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z,
18 #[derive(EnumSetType, Debug)]
20 _00, _01, _02, _03, _04, _05, _06, _07,
21 _10, _11, _12, _13, _14, _15, _16, _17,
22 _20, _21, _22, _23, _24, _25, _26, _27,
23 _30, _31, _32, _33, _34, _35, _36, _37,
24 _40, _41, _42, _43, _44, _45, _46, _47,
25 _50, _51, _52, _53, _54, _55, _56, _57,
26 _60, _61, _62, _63, _64, _65, _66, _67,
27 _70, _71, _72, _73, _74, _75, _76, _77,
28 A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z,
30 #[derive(EnumSetType, Debug)]
32 A, B, C, D, E, F, G, H,
34 #[derive(EnumSetType, Debug)]
36 A, B, C, D, E, F, G, H, _8, _9, _10, _11, _12, _13, _14, _15,
37 _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31,
38 _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47,
39 _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63,
40 _64, _65, _66, _67, _68, _69, _70, _71, _72, _73, _74, _75, _76, _77, _78, _79,
41 _80, _81, _82, _83, _84, _85, _86, _87, _88, _89, _90, _91, _92, _93, _94, _95,
42 _96, _97, _98, _99, _100, _101, _102, _103, _104, _105, _106, _107, _108, _109,
43 _110, _111, _112, _113, _114, _115, _116, _117, _118, _119, _120, _121, _122,
44 _123, _124, _125, _126, _127,
46 #[derive(EnumSetType, Debug)]
48 A = 0xA, B = 20, C = 30, D = 40, E = 50, F = 60, G = 70, H = 80,
52 #[derive(EnumSetType, Debug)]
54 A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z,
57 macro_rules! test_variants {
58 ($enum_name:ident $all_empty_test:ident $($variant:ident,)*) => {
60 fn $all_empty_test() {
61 let all = EnumSet::<$enum_name>::all();
62 let empty = EnumSet::<$enum_name>::empty();
65 assert!(!empty.contains($enum_name::$variant));
66 assert!(all.contains($enum_name::$variant));
71 test_variants! { SmallEnum small_enum_all_empty
72 A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z,
74 test_variants! { LargeEnum large_enum_all_empty
75 _00, _01, _02, _03, _04, _05, _06, _07,
76 _10, _11, _12, _13, _14, _15, _16, _17,
77 _20, _21, _22, _23, _24, _25, _26, _27,
78 _30, _31, _32, _33, _34, _35, _36, _37,
79 _40, _41, _42, _43, _44, _45, _46, _47,
80 _50, _51, _52, _53, _54, _55, _56, _57,
81 _60, _61, _62, _63, _64, _65, _66, _67,
82 _70, _71, _72, _73, _74, _75, _76, _77,
83 A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z,
85 test_variants! { SparseEnum sparse_enum_all_empty
89 macro_rules! test_enum {
90 ($e:ident, $mem_size:expr) => {
91 const CONST_SET: EnumSet<$e> = enum_set!($e::A | $e::C);
92 const EMPTY_SET: EnumSet<$e> = enum_set!();
95 assert_eq!(CONST_SET.len(), 2);
96 assert!(CONST_SET.contains($e::A));
97 assert!(CONST_SET.contains($e::C));
98 assert!(EMPTY_SET.is_empty());
102 fn basic_add_remove() {
103 let mut set = EnumSet::new();
107 assert_eq!(set, $e::A | $e::B | $e::C);
109 assert_eq!(set, $e::A | $e::C);
111 assert_eq!(set, $e::A | $e::C | $e::D);
112 set.insert_all($e::F | $e::E | $e::G);
113 assert_eq!(set, $e::A | $e::C | $e::D | $e::F | $e::E | $e::G);
114 set.remove_all($e::A | $e::D | $e::G);
115 assert_eq!(set, $e::C | $e::F | $e::E);
116 assert!(!set.is_empty());
118 assert!(set.is_empty());
122 fn already_present_element() {
123 let mut set = EnumSet::new();
124 assert!(set.insert($e::A));
125 assert!(!set.insert($e::A));
127 assert!(set.insert($e::A));
131 fn empty_is_empty() {
132 assert_eq!(EnumSet::<$e>::empty().len(), 0)
137 assert_eq!(EnumSet::<$e>::all().len(), EnumSet::<$e>::variant_count() as usize)
141 fn basic_iter_test() {
142 let mut set = EnumSet::new();
148 let mut set_2 = EnumSet::new();
149 let vec: Vec<$e> = set.iter().collect();
151 assert!(!set_2.contains(val));
154 assert_eq!(set, set_2);
156 let mut set_3 = EnumSet::new();
158 assert!(!set_3.contains(val));
161 assert_eq!(set, set_3);
164 fn check_iter_size_hint(set: EnumSet<$e>) {
165 let count = set.len();
166 let mut itr = set.iter();
167 for idx in 0 .. count {
168 assert_eq!(itr.size_hint(), (count-idx, Some(count-idx)));
169 assert!(itr.next().is_some());
171 assert_eq!(itr.size_hint(), (0, Some(0)));
174 fn test_iter_size_hint() {
175 check_iter_size_hint(EnumSet::<$e>::all());
176 let mut set = EnumSet::new();
180 check_iter_size_hint(set);
185 let set = $e::A | $e::B | $e::C | $e::E;
186 let set2 = set.iter().filter(|&v| v != $e::B).collect::<EnumSet<_>>();
187 assert_eq!(set2, $e::A | $e::C | $e::E);
191 fn basic_ops_test() {
192 assert_eq!(($e::A | $e::B) | ($e::B | $e::C), $e::A | $e::B | $e::C);
193 assert_eq!(($e::A | $e::B) & ($e::B | $e::C), $e::B);
194 assert_eq!(($e::A | $e::B) ^ ($e::B | $e::C), $e::A | $e::C);
195 assert_eq!(($e::A | $e::B) - ($e::B | $e::C), $e::A);
196 assert_eq!($e::A | !$e::A, EnumSet::<$e>::all());
200 fn mutable_ops_test() {
201 let mut set = $e::A | $e::B;
202 assert_eq!(set, $e::A | $e::B);
203 set |= $e::C | $e::D;
204 assert_eq!(set, $e::A | $e::B | $e::C | $e::D);
206 assert_eq!(set, $e::A | $e::B | $e::D);
207 set ^= $e::B | $e::E;
208 assert_eq!(set, $e::A | $e::D | $e::E);
209 set &= $e::A | $e::E | $e::F;
210 assert_eq!(set, $e::A | $e::E);
214 fn basic_set_status() {
215 assert!(($e::A | $e::B | $e::C).is_disjoint($e::D | $e::E | $e::F));
216 assert!(!($e::A | $e::B | $e::C | $e::D).is_disjoint($e::D | $e::E | $e::F));
217 assert!(($e::A | $e::B).is_subset($e::A | $e::B | $e::C));
218 assert!(!($e::A | $e::D).is_subset($e::A | $e::B | $e::C));
223 assert_eq!(format!("{:?}", $e::A | $e::B | $e::D), "EnumSet(A | B | D)");
228 let value = $e::A | $e::C | $e::D | $e::F | $e::E | $e::G;
229 assert_eq!(EnumSet::from_u128(value.to_u128()), value);
235 if EnumSet::<$e>::variant_count() == 128 {
236 panic!("(test skipped)")
238 EnumSet::<$e>::from_u128(!0);
242 fn match_const_test() {
244 CONST_SET => { /* ok */ }
245 _ => panic!("match fell through?"),
251 const SET_TEST_A: EnumSet<$e> = enum_set!($e::A | $e::B | $e::C);
252 const SET_TEST_B: EnumSet<$e> = enum_set!($e::A | $e::B | $e::D);
253 const SET_TEST_C: EnumSet<$e> = enum_set!($e::A | $e::B | $e::E);
254 const SET_TEST_D: EnumSet<$e> = enum_set!($e::A | $e::B | $e::F);
255 const SET_TEST_E: EnumSet<$e> = enum_set!($e::A | $e::B | $e::G);
256 macro_rules! test_set {
258 assert!(!$set.contains(&SET_TEST_A));
259 assert!(!$set.contains(&SET_TEST_B));
260 assert!(!$set.contains(&SET_TEST_C));
261 assert!(!$set.contains(&SET_TEST_D));
262 assert!(!$set.contains(&SET_TEST_E));
263 $set.insert(SET_TEST_A);
264 $set.insert(SET_TEST_C);
265 assert!($set.contains(&SET_TEST_A));
266 assert!(!$set.contains(&SET_TEST_B));
267 assert!($set.contains(&SET_TEST_C));
268 assert!(!$set.contains(&SET_TEST_D));
269 assert!(!$set.contains(&SET_TEST_E));
270 $set.remove(&SET_TEST_C);
271 $set.remove(&SET_TEST_D);
272 assert!($set.contains(&SET_TEST_A));
273 assert!(!$set.contains(&SET_TEST_B));
274 assert!(!$set.contains(&SET_TEST_C));
275 assert!(!$set.contains(&SET_TEST_D));
276 assert!(!$set.contains(&SET_TEST_E));
277 $set.insert(SET_TEST_A);
278 $set.insert(SET_TEST_D);
279 assert!($set.contains(&SET_TEST_A));
280 assert!(!$set.contains(&SET_TEST_B));
281 assert!(!$set.contains(&SET_TEST_C));
282 assert!($set.contains(&SET_TEST_D));
283 assert!(!$set.contains(&SET_TEST_E));
287 let mut hash_set = HashSet::new();
290 let mut tree_set = BTreeSet::new();
296 assert_eq!(::std::mem::size_of::<EnumSet<$e>>(), $mem_size);
301 ($m:ident, $($tt:tt)*) => { mod $m { use super::*; $($tt)*; } }
304 tests!(small_enum, test_enum!(SmallEnum, 4));
305 tests!(large_enum, test_enum!(LargeEnum, 16));
306 tests!(enum8, test_enum!(Enum8, 1));
307 tests!(enum128, test_enum!(Enum128, 16));
308 tests!(sparse_enum, test_enum!(SparseEnum, 16));
309 tests!(repr_enum, test_enum!(ReprEnum, 4));
311 #[derive(EnumSetType, Debug)]
312 pub enum ThresholdEnum {
314 U8 = 0, U16 = 8, U32 = 16, U64 = 32, U128 = 64,
316 macro_rules! bits_tests {
318 $mod_name:ident, $threshold_expr:expr, ($($too_big_expr:expr),*), $ty:ty,
319 $to:ident $try_to:ident $to_truncated:ident
320 $from:ident $try_from:ident $from_truncated:ident
324 use crate::ThresholdEnum::*;
329 $threshold_expr | B | C | D,
330 $threshold_expr | A | D,
331 $threshold_expr | B | C,
333 assert_eq!(mask, EnumSet::<ThresholdEnum>::$from(mask.$to()));
334 assert_eq!(mask.$to_truncated(), mask.$to());
335 assert_eq!(Some(mask.$to()), mask.$try_to())
342 let invalid_mask: $ty = 0x80;
343 EnumSet::<ThresholdEnum>::$from(invalid_mask);
347 fn try_from_invalid() {
348 assert!(EnumSet::<ThresholdEnum>::$try_from(0xFF).is_none());
353 fn try_to_overflow() {
354 let set: EnumSet<ThresholdEnum> = $too_big_expr.into();
355 assert!(set.$try_to().is_none());
360 fn truncated_overflow() {
361 let trunc_invalid = EnumSet::<ThresholdEnum>::$from_truncated(0xFE);
362 assert_eq!(A | B | C | D, trunc_invalid);
364 let set: EnumSet<ThresholdEnum> = $too_big_expr | A;
365 assert_eq!(2, set.$to_truncated());
372 bits_tests!(test_u8_bits, U8, (U16), u8,
373 to_u8 to_u8_checked to_u8_truncated from_u8 try_from_u8 from_u8_truncated);
374 bits_tests!(test_u16_bits, U16, (U32), u16,
375 to_u16 to_u16_checked to_u16_truncated from_u16 try_from_u16 from_u16_truncated);
376 bits_tests!(test_u32_bits, U32, (U64), u32,
377 to_u32 to_u32_checked to_u32_truncated from_u32 try_from_u32 from_u32_truncated);
378 bits_tests!(test_u64_bits, U64, (U128), u64,
379 to_u64 to_u64_checked to_u64_truncated from_u64 try_from_u64 from_u64_truncated);
380 bits_tests!(test_u128_bits, U128, (), u128,
381 to_u128 to_u128_checked to_u128_truncated from_u128 try_from_u128 from_u128_truncated);