auto_bitflags/
lib.rs

1///Helper macro for auto_bitflags, don't call this directly.
2#[macro_export]
3macro_rules! auto_bitflags_h {
4   (u16, $shift_num:expr, $flag_name:ident) => {
5        const $flag_name: u16 = 1 << $shift_num;
6   };
7   
8   (u32, $shift_num:expr, $flag_name:ident) => {
9        const $flag_name: u32 = 1 << $shift_num;
10   };
11   
12   (u64, $shift_num:expr, $flag_name:ident) => {
13        const $flag_name: u64 = 1 << $shift_num;
14   };
15}
16
17///Logarithmic identifier counting macro.
18#[macro_export]
19macro_rules! count_idents {
20    ()        => {0usize};
21    ($one:ident) => {1usize};
22    ($($pairs:ident, $_p:ident), *) => {
23        count_idents!($($pairs), *) << 1usize
24    };
25    ($odd:ident, $($rest:ident), *) => {
26        count_idents!($($rest), *) | 1usize
27    };
28}
29
30///The auto_bitflags! macros generates const bitflags,
31///the values are assigned in descending order.
32///
33///# Examples
34///
35///```
36///# #[macro_use] extern crate auto_bitflags;
37///auto_bitflags!(u32, FLAG_FLAG1, FLAG_FLAG2);
38///# fn main() {
39///assert_eq!(0b11, FLAG_FLAG1 | FLAG_FLAG2);
40///let flag12 = FLAG_FLAG1 | FLAG_FLAG2;
41///assert_eq!(0b1, flag12 & FLAG_FLAG2);
42///assert_eq!(0b10, flag12 & FLAG_FLAG1);
43///# }
44///```
45#[macro_export]
46macro_rules! auto_bitflags {
47    (u16, $flag:ident, $($flagrest:ident), *) => {
48        auto_bitflags_h!(u16, count_idents!($($flagrest),*), $flag);
49        auto_bitflags!(u16, $($flagrest), *);
50    };
51    (u16, $flag:ident) => {
52        auto_bitflags_h!(u16, 0, $flag);
53    };
54
55    (u32, $flag:ident, $($flagrest:ident), *) => {
56        auto_bitflags_h!(u32, count_idents!($($flagrest),*), $flag);
57        auto_bitflags!(u32, $($flagrest), *);
58    };
59    (u32, $flag:ident) => {
60        auto_bitflags_h!(u32, 0, $flag);
61    };
62
63    (u64, $flag:ident, $($flagrest:ident), *) => {
64        auto_bitflags_h!(u64, count_idents!($($flagrest),*), $flag);
65        auto_bitflags!(u64, $($flagrest), *);
66    };
67    (u64, $flag:ident) => {
68        auto_bitflags_h!(u64, 0, $flag);
69    };
70}
71
72#[cfg(test)]
73mod tests {
74    auto_bitflags!(u16, FLAG_T1_16, FLAG_T2_16);
75    #[test]
76    fn test_u16() {
77        assert_eq!(0b11, FLAG_T1_16 | FLAG_T2_16);
78    }
79
80    auto_bitflags!(u32, FLAG_T1_32, FLAG_T2_32);
81    #[test]
82    fn test_u32() {
83        assert_eq!(0b11, FLAG_T1_32 | FLAG_T2_32);
84    }
85
86    auto_bitflags!(u64, FLAG_T1_64, FLAG_T2_64);
87    #[test]
88    fn test_u64() {
89        assert_eq!(0b11, FLAG_T1_64 | FLAG_T2_64);
90    }
91}