-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbitflags.ltl
More file actions
102 lines (87 loc) · 2.74 KB
/
Copy pathbitflags.ltl
File metadata and controls
102 lines (87 loc) · 2.74 KB
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
// Lateralus Standard Library — Bit Flags
// Type-safe bitflag operations for system programming
/// A set of named bit flags backed by a u64
struct BitFlags {
value: u64,
names: [(str, u64)],
}
impl BitFlags {
/// Create an empty flag set
pub fn new() -> BitFlags {
BitFlags { value: 0, names: [] }
}
/// Create from a raw integer value
pub fn from_raw(value: u64) -> BitFlags {
BitFlags { value, names: [] }
}
/// Define a named flag
pub fn define(mut self, name: str, bit: u64) -> BitFlags {
self.names.push((name, 1u64 << bit))
self
}
/// Set a flag by name
pub fn set(mut self, name: str) -> Result<BitFlags, str> {
let mask = self.names
|> find(|(n, _)| n == name)
|> map(|(_, m)| m)
|> ok_or("Unknown flag: {name}")?
self.value |= mask
Ok(self)
}
/// Clear a flag by name
pub fn clear(mut self, name: str) -> Result<BitFlags, str> {
let mask = self.names
|> find(|(n, _)| n == name)
|> map(|(_, m)| m)
|> ok_or("Unknown flag: {name}")?
self.value &= !mask
Ok(self)
}
/// Toggle a flag by name
pub fn toggle(mut self, name: str) -> Result<BitFlags, str> {
let mask = self.names
|> find(|(n, _)| n == name)
|> map(|(_, m)| m)
|> ok_or("Unknown flag: {name}")?
self.value ^= mask
Ok(self)
}
/// Check if a flag is set
pub fn has(self, name: str) -> bool {
self.names
|> find(|(n, _)| n == name)
|> map(|(_, m)| self.value & m != 0)
|> unwrap_or(false)
}
/// Check if all given flags are set
pub fn has_all(self, names: [str]) -> bool {
names |> all(|n| self.has(n))
}
/// Check if any of the given flags are set
pub fn has_any(self, names: [str]) -> bool {
names |> any(|n| self.has(n))
}
/// Get raw value
pub fn raw(self) -> u64 { self.value }
/// Union of two flag sets
pub fn union(self, other: BitFlags) -> BitFlags {
BitFlags { value: self.value | other.value, names: self.names }
}
/// Intersection of two flag sets
pub fn intersect(self, other: BitFlags) -> BitFlags {
BitFlags { value: self.value & other.value, names: self.names }
}
/// List all active flag names
pub fn active(self) -> [str] {
self.names
|> filter(|(_, m)| self.value & m != 0)
|> map(|(n, _)| n)
|> collect
}
/// Display as a human-readable string
pub fn to_string(self) -> str {
let flags = self.active()
if flags.is_empty() { "(none)" }
else { flags |> join(" | ") }
}
}