virtio_spec/
bitflags.rs

1macro_rules! _bitflags_base {
2    (
3        $(#[$outer:meta])*
4        $vis:vis struct $BitFlags:ident: $T:ty;
5
6        $($t:tt)*
7    ) => {
8        #[cfg_attr(
9            feature = "zerocopy",
10            derive(
11                zerocopy_derive::KnownLayout,
12                zerocopy_derive::Immutable,
13                zerocopy_derive::FromBytes,
14                zerocopy_derive::IntoBytes,
15            )
16        )]
17        #[derive(Default, Clone, Copy, PartialEq, Eq, Hash)]
18        #[repr(transparent)]
19        $(#[$outer])*
20        $vis struct $BitFlags($T);
21
22        impl ::core::fmt::Debug for $BitFlags {
23            fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
24                struct Inner<'a>(&'a $BitFlags);
25
26                impl<'a> ::core::fmt::Debug for Inner<'a> {
27                    fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
28                        if self.0.is_empty() {
29                            f.write_str("0x0")
30                        } else {
31                            ::bitflags::parser::to_writer(self.0, f)
32                        }
33                    }
34                }
35
36                f.debug_tuple(::core::stringify!($BitFlags))
37                    .field(&Inner(self))
38                    .finish()
39            }
40        }
41
42        _bitflags_base! {
43            $($t)*
44        }
45    };
46    () => {};
47}
48
49macro_rules! virtio_bitflags {
50    (
51        $(#[$outer:meta])*
52        $vis:vis struct $BitFlags:ident: $T:ty {
53            $(
54                $(#[$inner:ident $($args:tt)*])*
55                const $Flag:tt = $value:expr;
56            )*
57        }
58
59        $($t:tt)*
60    ) => {
61        _bitflags_base! {
62            $(#[$outer])*
63            $vis struct $BitFlags: $T;
64        }
65
66        ::bitflags::bitflags! {
67            impl $BitFlags: $T {
68                $(
69                    $(#[$inner $($args)*])*
70                    const $Flag = $value;
71                )*
72
73                const _ = !0;
74            }
75        }
76
77        virtio_bitflags! {
78            $($t)*
79        }
80    };
81    () => {};
82}
83
84macro_rules! impl_fmt {
85    ($Trait:ident for $SelfT:ty) => {
86        impl ::core::fmt::$Trait for $SelfT {
87            fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
88                self.0.fmt(f)
89            }
90        }
91    };
92}
93
94macro_rules! endian_bitflags {
95    (
96        $(#[$outer:meta])*
97        $vis:vis struct $BitFlags:ident: $T:ty {
98            $(
99                $(#[$inner:ident $($args:tt)*])*
100                const $Flag:tt = $value:expr;
101            )*
102        }
103
104        $($t:tt)*
105    ) => {
106        _bitflags_base! {
107            $(#[$outer])*
108            $vis struct $BitFlags: $T;
109        }
110
111        impl $BitFlags {
112            $(
113                $(#[$inner $($args)*])*
114                pub const $Flag: Self = Self(<$T>::from_ne($value));
115            )*
116        }
117
118        impl ::bitflags::Flags for $BitFlags {
119            const FLAGS: &'static [::bitflags::Flag<Self>] = &[
120                $(
121                    ::bitflags::Flag::new(::core::stringify!($Flag), Self::$Flag),
122                )*
123                ::bitflags::Flag::new("", Self::all()),
124            ];
125
126            type Bits = $T;
127
128            fn from_bits_retain(bits: Self::Bits) -> Self {
129                Self(bits)
130            }
131
132            fn bits(&self) -> Self::Bits {
133                self.0
134            }
135        }
136
137        impl $BitFlags{
138            /// Get a flags value with all bits unset.
139            #[inline]
140            pub const fn empty() -> Self {
141                Self(<$T as ::bitflags::Bits>::EMPTY)
142            }
143
144            /// Get a flags value with all known bits set.
145            #[inline]
146            pub const fn all() -> Self {
147                Self(<$T as ::bitflags::Bits>::ALL)
148            }
149
150            /// Get the underlying bits value.
151            ///
152            /// The returned value is exactly the bits set in this flags value.
153            #[inline]
154            pub const fn bits(&self) -> $T {
155                self.0
156            }
157
158            /// Convert from a bits value.
159            ///
160            /// This method will return `None` if any unknown bits are set.
161            #[inline]
162            pub const fn from_bits(bits: $T) -> Option<Self> {
163                Some(Self(bits))
164            }
165
166            /// Convert from a bits value, unsetting any unknown bits.
167            #[inline]
168            pub const fn from_bits_truncate(bits: $T) -> Self {
169                Self(bits)
170            }
171
172            /// Convert from a bits value exactly.
173            #[inline]
174            pub const fn from_bits_retain(bits: $T) -> Self {
175                Self(bits)
176            }
177
178            /// Get a flags value with the bits of a flag with the given name set.
179            ///
180            /// This method will return `None` if `name` is empty or doesn't
181            /// correspond to any named flag.
182            #[inline]
183            pub fn from_name(name: &str) -> Option<Self> {
184                <Self as ::bitflags::Flags>::from_name(name)
185            }
186
187            /// Whether all bits in this flags value are unset.
188            #[inline]
189            pub const fn is_empty(&self) -> bool {
190                self.bits().to_ne() == <$T as ::bitflags::Bits>::EMPTY.to_ne()
191            }
192
193            /// Whether all known bits in this flags value are set.
194            #[inline]
195            pub const fn is_all(&self) -> bool {
196                Self::all().bits().to_ne() | self.bits().to_ne() == self.bits().to_ne()
197            }
198
199            /// Whether any set bits in a source flags value are also set in a target flags value.
200            #[inline]
201            pub const fn intersects(&self, other: Self) -> bool {
202                self.bits().to_ne() & other.bits().to_ne() != <$T as ::bitflags::Bits>::EMPTY.to_ne()
203            }
204
205            /// Whether all set bits in a source flags value are also set in a target flags value.
206            #[inline]
207            pub const fn contains(&self, other: Self) -> bool {
208                self.bits().to_ne() & other.bits().to_ne() == other.bits().to_ne()
209            }
210
211            /// The bitwise or (`|`) of the bits in two flags values.
212            #[inline]
213            pub fn insert(&mut self, other: Self) {
214                *self = Self::from_bits_retain(self.bits()).union(other);
215            }
216
217            /// The intersection of a source flags value with the complement of a target flags value (`&!`).
218            ///
219            /// This method is not equivalent to `self & !other` when `other` has unknown bits set.
220            /// `remove` won't truncate `other`, but the `!` operator will.
221            #[inline]
222            pub fn remove(&mut self, other: Self) {
223                *self = Self::from_bits_retain(self.bits()).difference(other);
224            }
225
226            /// The bitwise exclusive-or (`^`) of the bits in two flags values.
227            #[inline]
228            pub fn toggle(&mut self, other: Self) {
229                *self = Self::from_bits_retain(self.bits()).symmetric_difference(other);
230            }
231
232            /// Call `insert` when `value` is `true` or `remove` when `value` is `false`.
233            #[inline]
234            pub fn set(&mut self, other: Self, value: bool) {
235                if value {
236                    self.insert(other);
237                } else {
238                    self.remove(other);
239                }
240            }
241
242            /// The bitwise and (`&`) of the bits in two flags values.
243            #[inline]
244            #[must_use]
245            pub const fn intersection(self, other: Self) -> Self {
246                Self::from_bits_retain(<$T>::from_ne(self.bits().to_ne() & other.bits().to_ne()))
247            }
248
249            /// The bitwise or (`|`) of the bits in two flags values.
250            #[inline]
251            #[must_use]
252            pub const fn union(self, other: Self) -> Self {
253                Self::from_bits_retain(<$T>::from_ne(self.bits().to_ne() | other.bits().to_ne()))
254            }
255
256            /// The intersection of a source flags value with the complement of a target flags value (`&!`).
257            ///
258            /// This method is not equivalent to `self & !other` when `other` has unknown bits set.
259            /// `difference` won't truncate `other`, but the `!` operator will.
260            #[inline]
261            #[must_use]
262            pub const fn difference(self, other: Self) -> Self {
263                Self::from_bits_retain(<$T>::from_ne(self.bits().to_ne() & !other.bits().to_ne()))
264            }
265
266            /// The bitwise exclusive-or (`^`) of the bits in two flags values.
267            #[inline]
268            #[must_use]
269            pub const fn symmetric_difference(self, other: Self) -> Self {
270                Self::from_bits_retain(<$T>::from_ne(self.bits().to_ne() ^ other.bits().to_ne()))
271            }
272
273            /// The bitwise negation (`!`) of the bits in a flags value, truncating the result.
274            #[inline]
275            #[must_use]
276            pub const fn complement(self) -> Self {
277                Self::from_bits_truncate(<$T>::from_ne(!self.bits().to_ne()))
278            }
279        }
280
281        impl_fmt!(Binary for $BitFlags);
282        impl_fmt!(Octal for $BitFlags);
283        impl_fmt!(LowerHex for $BitFlags);
284        impl_fmt!(UpperHex for $BitFlags);
285
286        impl ::core::ops::BitOr for $BitFlags {
287            type Output = Self;
288
289            /// The bitwise or (`|`) of the bits in two flags values.
290            #[inline]
291            fn bitor(self, other: Self) -> Self {
292                self.union(other)
293            }
294        }
295
296        impl ::core::ops::BitOrAssign for $BitFlags {
297            /// The bitwise or (`|`) of the bits in two flags values.
298            #[inline]
299            fn bitor_assign(&mut self, other: Self) {
300                self.insert(other);
301            }
302        }
303
304        impl ::core::ops::BitXor for $BitFlags {
305            type Output = Self;
306
307            /// The bitwise exclusive-or (`^`) of the bits in two flags values.
308            #[inline]
309            fn bitxor(self, other: Self) -> Self {
310                self.symmetric_difference(other)
311            }
312        }
313
314        impl ::core::ops::BitXorAssign for $BitFlags {
315            /// The bitwise exclusive-or (`^`) of the bits in two flags values.
316            #[inline]
317            fn bitxor_assign(&mut self, other: Self) {
318                self.toggle(other);
319            }
320        }
321
322        impl ::core::ops::BitAnd for $BitFlags {
323            type Output = Self;
324
325            /// The bitwise and (`&`) of the bits in two flags values.
326            #[inline]
327            fn bitand(self, other: Self) -> Self {
328                self.intersection(other)
329            }
330        }
331
332        impl ::core::ops::BitAndAssign for $BitFlags {
333            /// The bitwise and (`&`) of the bits in two flags values.
334            #[inline]
335            fn bitand_assign(&mut self, other: Self) {
336                *self = Self::from_bits_retain(self.bits()).intersection(other);
337            }
338        }
339
340        impl ::core::ops::Sub for $BitFlags {
341            type Output = Self;
342
343            /// The intersection of a source flags value with the complement of a target flags value (`&!`).
344            ///
345            /// This method is not equivalent to `self & !other` when `other` has unknown bits set.
346            /// `difference` won't truncate `other`, but the `!` operator will.
347            #[inline]
348            fn sub(self, other: Self) -> Self {
349                self.difference(other)
350            }
351        }
352
353        impl ::core::ops::SubAssign for $BitFlags {
354            /// The intersection of a source flags value with the complement of a target flags value (`&!`).
355            ///
356            /// This method is not equivalent to `self & !other` when `other` has unknown bits set.
357            /// `difference` won't truncate `other`, but the `!` operator will.
358            #[inline]
359            fn sub_assign(&mut self, other: Self) {
360                self.remove(other);
361            }
362        }
363
364        impl ::core::ops::Not for $BitFlags {
365            type Output = Self;
366
367            /// The bitwise negation (`!`) of the bits in a flags value, truncating the result.
368            #[inline]
369            fn not(self) -> Self {
370                self.complement()
371            }
372        }
373
374        impl ::core::iter::Extend<$BitFlags> for $BitFlags {
375            /// The bitwise or (`|`) of the bits in each flags value.
376            fn extend<T>(&mut self, iterator: T)
377            where
378                T: ::core::iter::IntoIterator<Item = Self>,
379            {
380                for item in iterator {
381                    self.insert(item)
382                }
383            }
384        }
385
386        impl ::core::iter::FromIterator<$BitFlags> for $BitFlags {
387            /// The bitwise or (`|`) of the bits in each flags value.
388            fn from_iter<T>(iterator: T) -> Self
389            where
390                T: ::core::iter::IntoIterator<Item = Self>,
391            {
392                use ::core::iter::Extend;
393
394                let mut result = Self::empty();
395                result.extend(iterator);
396                result
397            }
398        }
399
400        impl $BitFlags {
401            /// Yield a set of contained flags values.
402            ///
403            /// Each yielded flags value will correspond to a defined named flag. Any unknown bits
404            /// will be yielded together as a final flags value.
405            #[inline]
406            pub fn iter(&self) -> ::bitflags::iter::Iter<Self> {
407                ::bitflags::Flags::iter(self)
408            }
409
410            /// Yield a set of contained named flags values.
411            ///
412            /// This method is like [`iter`](#method.iter), except only yields bits in contained named flags.
413            /// Any unknown bits, or bits not corresponding to a contained flag will not be yielded.
414            #[inline]
415            pub fn iter_names(&self) -> ::bitflags::iter::IterNames<Self> {
416                ::bitflags::Flags::iter_names(self)
417            }
418        }
419
420        impl ::core::iter::IntoIterator for $BitFlags {
421            type Item = Self;
422            type IntoIter = ::bitflags::iter::Iter<Self::Item>;
423            fn into_iter(self) -> Self::IntoIter {
424                self.iter()
425            }
426        }
427
428        endian_bitflags! {
429            $($t)*
430        }
431    };
432    () => {};
433}