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
use std::ops::{
BitOrAssign,
BitXorAssign,
BitAndAssign,
Not,
BitAnd,
};
pub trait BitMaskable
where Self: Copy +
BitOrAssign +
BitXorAssign +
BitAndAssign +
Not<Output = Self> +
BitAnd<Self, Output = Self> +
Eq,
{
fn mask(&mut self, mask: Self);
fn flip(&mut self, mask: Self);
fn unmask(&mut self, mask: Self);
fn masked(self, mask: Self) -> bool;
}
impl <B> BitMaskable for B
where B: Copy +
BitOrAssign +
BitXorAssign +
BitAndAssign +
Not<Output = B> +
BitAnd<B, Output = B> +
Eq,
{
#[inline(always)]
fn mask(&mut self, mask: B) {
*self |= mask;
}
#[inline(always)]
fn flip(&mut self, mask: B) {
*self ^= mask;
}
#[inline(always)]
fn unmask(&mut self, mask: B) {
*self &= !mask;
}
#[inline(always)]
fn masked(self, mask: B) -> bool {
self & mask == mask
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn mask_works() {
let mut m: u32 = 0;
m.mask(128);
assert!(m.masked(128));
m.unmask(128);
assert!(!m.masked(128));
}
#[test]
fn flip_works() {
let mut m: u32 = 0;
m.flip(128);
assert!(m.masked(128));
m.flip(128);
assert!(!m.masked(128));
}
#[test]
fn multi_masks_work() {
let mut m: u32 = 0;
m.mask(1|2|4);
assert!(m.masked(1|2|4));
assert!(m.masked(2|4));
assert!(!m.masked(1|2|4|8));
m.unmask(2|4|8);
assert!(m.masked(1));
}
}