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
117
118
119
120
121
122
123
124
125
#[macro_export]
macro_rules! const_flag {
// The pattern for a single bitflag
($t:ty, $e:ident) => {
<$t>::$e
};
// Combine multiple bitflags passing directly to `bitor_variadic!()`
($t:ty, $($rest:ident),*) => {
<$t>::from_bits_truncate(
$crate::bitor_variadic!($t, $($rest),*)
)
};
// Combine multiple bitflags passing directly to `bitor_variadic!()`
($name:ident, $t:ty, $($rest:ident),*) => {
const $name: $t = <$t>::from_bits_truncate(
$crate::bitor_variadic!($t, $($rest),*)
);
};
}
#[macro_export]
macro_rules! pub_const_flag {
// The pattern for a single bitflag
($name:ident : $t:ty = $($rest:ident)|*) => {
pub const $name: $t = <$t>::from_bits_truncate(
$crate::bitor_variadic!($t, $($rest),*)
);
};
}
#[macro_export]
macro_rules! bitor {
($name:ident : $t:ty = $($rest:ident)|*) => {
let $name: $t = <$t>::from_bits_truncate(
$crate::bitor_variadic!($t, $($rest),*)
);
};
($t:ty : $($rest:ident)|*) => {
<$t>::from_bits_truncate(
$crate::bitor_variadic!($t, $($rest),*)
)
};
}
#[macro_export]
// Used by `const_flags!` to combine bitflags using | on .bits()
macro_rules! bitor_variadic {
// Match the trivial case
($t:ty, $i:ident) => {
<$t>::$i.bits()
};
// Match case with two identifiers
// They will need to be :: then call .bits() before | operator
($t:ty, $i1:ident, $i2:ident) => {
<$t>::$i1.bits() | <$t>::$i2.bits()
};
// Match case with list of identifiers
// This will be the topmost macro, with none of the arguments being eval yet.
($t:ty, $i1:ident, $i2:ident, $($rest:ident), *) => {
// f expr
$crate::bitor_variadic!($t, <$t>::$i1.bits() | <$t>::$i2.bits(), $($rest), *)
};
// Match case with expr and list of idents
// When the first argument is an expr, it has been :: and .bits() already
// so we just append the next argument with :: and | to the expr
($t:ty, $e:expr, $i:ident, $($rest:ident), *) => {
$crate::bitor_variadic!($t, $e | <$t>::$i.bits(), $($rest), *)
};
// Match case with expr and ident
// This will be the final macro call
($t:ty, $e:expr, $i:ident) => {
$e | <$t>::$i.bits()
};
}
// Internal use macro to (ab)use Deref trait to get the underlying wgpu type
#[macro_export]
macro_rules! wgpu_inner_deref {
($name: tt, $wgpu: tt) => {
impl ::std::ops::Deref for $name {
type Target = ::wgpu::$wgpu;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
impl ::std::ops::DerefMut for $name {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.inner
}
}
};
($name: tt<'_>, $wgpu: tt) => {
impl ::std::ops::Deref for $name<'_> {
type Target = ::wgpu::$wgpu;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
impl ::std::ops::DerefMut for $name<'_> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.inner
}
}
};
($name: tt <$($gen: tt),*>, $wgpu: tt) => {
impl<$($gen),*> ::std::ops::Deref for $name<$($gen),*> {
type Target = ::wgpu::$wgpu;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
impl<$($gen),*> ::std::ops::DerefMut for $name<$($gen),*> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.inner
}
}
};
($name: tt) => {
// We shouldn't need the `$crate` but it won't compile without it
$crate::wgpu_inner_deref!($name, $name);
};
}