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
#[macro_export]
macro_rules! make_set_type {
($name:ident ($internal:ident) / $type:ident) => {
use std::ops::*;
#[doc = "A bit set of for filtering and/or smaller costs of storage."]
#[derive(Clone, Copy, Default, PartialEq, PartialOrd, Eq, Ord, Serialize, Deserialize)]
pub struct $name($internal);
impl $name {
pub fn new() -> Self {
$name(0)
}
#[doc = "Self contains type"]
pub fn has<T: Into<$type>>(self, other: T) -> bool {
let amp = self.0 & (1 << other.into() as u8);
amp != 0
}
#[doc = "Self is contained in part by other"]
pub fn contains<T: Into<Self>>(self, other: T) -> bool {
(self & other.into()).0 != 0
}
#[doc = "Self is contained in full by other"]
pub fn contained<T: Into<Self>>(self, other: T) -> bool {
(self & other.into()) == self
}
}
#[doc = "Utility for converting a single type into a set of itself"]
impl<T: Into<$type>> From<T> for $name {
fn from(val: T) -> Self {
$name(1 << val.into() as u8)
}
}
#[doc = "Utility for converting an optional type into a set of itself (with full state if none)"]
impl<T: Into<$name>> From<Option<T>> for $name {
fn from(val: Option<T>) -> Self {
if let Some(v) = val { v.into() }
else { $name($internal::max_value()) }
}
}
#[doc = "Utility for converting a list of type-alike into a set of type"]
impl<T: Into<$type>> From<Vec<T>> for $name {
fn from(list: Vec<T>) -> Self {
let mut data = $name(0);
for child in list {
data += child.into();
}
data
}
}
#[doc = "Utility for the opposite of this set"]
impl Not for $name {
type Output = Self;
fn not(self) -> Self {
$name(!self.0)
}
}
#[allow(clippy::suspicious_op_assign_impl)]
#[doc = "Utility for adding type to this bit set"]
impl AddAssign<$type> for $name {
fn add_assign(&mut self, rhs: $type) {
self.0 |= 1 << rhs as u8;
}
}
#[doc = "Utility for removing type from this bit set"]
impl SubAssign<$type> for $name {
fn sub_assign(&mut self, rhs: $type) {
self.0 &= !(1 << rhs as u8);
}
}
#[doc = "Utility for combining two sets"]
impl BitOrAssign for $name {
fn bitor_assign(&mut self, rhs: Self) {
self.0 |= rhs.0;
}
}
#[doc = "Utility for the difference of two sets"]
impl BitXor for $name {
type Output = Self;
fn bitxor(self, rhs: Self) -> Self {
$name(self.0 ^ rhs.0)
}
}
#[doc = "Utility for combining two sets"]
impl BitOr for $name {
type Output = Self;
fn bitor(self, rhs: Self) -> Self {
$name(self.0 | rhs.0)
}
}
#[doc = "Utility for the intersection of two sets"]
impl BitAnd for $name {
type Output = Self;
fn bitand(self, rhs: Self) -> Self {
$name(self.0 & rhs.0)
}
}
};
}