1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
#![macro_use]
macro_rules! flags_ops {
($flagset:ident: $ty:ty: $flags:ident: $($case:ident,)*) => (
impl ::std::ops::BitOr<$flags> for $flags {
type Output = $flagset;
fn bitor(self, rhs: $flags) -> Self::Output {
$flagset::from(self) | $flagset::from(rhs)
}
}
impl $flagset {
pub fn none() -> Self {
$flagset(0)
}
}
impl ::std::fmt::Debug for $flagset {
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
write!(f, "[")?;
$(
if *self & $flags::$case {
write!(f, "{:?},", $flags::$case)?;
}
)*
write!(f, "]")
}
}
impl ::std::default::Default for $flagset {
fn default() -> Self {
$flagset(0)
}
}
impl ::std::convert::From<$flags> for $flagset {
fn from(flag: $flags) -> Self {
$flagset(1 << (flag as u8))
}
}
impl ::std::convert::Into<$ty> for $flagset {
fn into(self) -> $ty {
self.0
}
}
impl ::std::ops::BitOr<$flags> for $flagset {
type Output = $flagset;
fn bitor(self, rhs: $flags) -> Self::Output {
self | $flagset::from(rhs)
}
}
impl ::std::ops::BitOr<$flagset> for $flagset {
type Output = $flagset;
fn bitor(self, rhs: $flagset) -> Self::Output {
$flagset(self.0 | rhs.0)
}
}
impl<T> ::std::ops::BitOrAssign<T> for $flagset
where $flagset: ::std::ops::BitOr<T, Output=$flagset> {
fn bitor_assign(&mut self, rhs: T) {
*self = *self | rhs;
}
}
impl ::std::ops::BitAnd<$flags> for $flagset {
type Output = bool;
fn bitand(self, rhs: $flags) -> Self::Output {
0 != (self.0 & $flagset::from(rhs).0)
}
}
impl ::std::ops::BitAnd<$flagset> for $flags {
type Output = bool;
fn bitand(self, rhs: $flagset) -> Self::Output {
0 != ($flagset::from(self).0 & rhs.0)
}
}
);
}
macro_rules! flag_mapping {
($flagset:ident: $flags:ident => $ty:ty:
$($case:ident => $value:expr,)*
) => (
impl Into<$ty> for $flagset {
fn into(self) -> $ty {
$(
(if self & $flags::$case {
$value
} else {
0
})
|)*
0
}
}
impl From<$ty> for $flagset {
fn from(value: $ty) -> Self {
$(
(if 0 != value & $value {
$flags::$case.into()
} else {
$flagset::none()
})
|)*
$flagset::none()
}
}
);
}