|
8 | 8 | // option. This file may not be copied, modified, or distributed |
9 | 9 | // except according to those terms. |
10 | 10 |
|
11 | | -//! The `bitflags!` macro generates a `struct` that holds a set of C-style |
12 | | -//! bitmask flags. It is useful for creating typesafe wrappers for C APIs. |
13 | | -//! |
14 | | -//! The flags should only be defined for integer types, otherwise unexpected |
15 | | -//! type errors may occur at compile time. |
16 | | -//! |
17 | | -//! # Example |
18 | | -//! |
19 | | -//! ~~~rust |
20 | | -//! bitflags!( |
21 | | -//! flags Flags: u32 { |
22 | | -//! static FlagA = 0x00000001, |
23 | | -//! static FlagB = 0x00000010, |
24 | | -//! static FlagC = 0x00000100, |
25 | | -//! static FlagABC = FlagA.bits |
26 | | -//! | FlagB.bits |
27 | | -//! | FlagC.bits |
28 | | -//! } |
29 | | -//! ) |
30 | | -//! |
31 | | -//! fn main() { |
32 | | -//! let e1 = FlagA | FlagC; |
33 | | -//! let e2 = FlagB | FlagC; |
34 | | -//! assert!((e1 | e2) == FlagABC); // union |
35 | | -//! assert!((e1 & e2) == FlagC); // intersection |
36 | | -//! assert!((e1 - e2) == FlagA); // set difference |
37 | | -//! assert!(!e2 == FlagA); // set complement |
38 | | -//! } |
39 | | -//! ~~~ |
40 | | -//! |
41 | | -//! The generated `struct`s can also be extended with type and trait implementations: |
42 | | -//! |
43 | | -//! ~~~rust |
44 | | -//! use std::fmt; |
45 | | -//! |
46 | | -//! bitflags!( |
47 | | -//! flags Flags: u32 { |
48 | | -//! static FlagA = 0x00000001, |
49 | | -//! static FlagB = 0x00000010 |
50 | | -//! } |
51 | | -//! ) |
52 | | -//! |
53 | | -//! impl Flags { |
54 | | -//! pub fn clear(&mut self) { |
55 | | -//! self.bits = 0; // The `bits` field can be accessed from within the |
56 | | -//! // same module where the `bitflags!` macro was invoked. |
57 | | -//! } |
58 | | -//! } |
59 | | -//! |
60 | | -//! impl fmt::Show for Flags { |
61 | | -//! fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
62 | | -//! write!(f, "hi!") |
63 | | -//! } |
64 | | -//! } |
65 | | -//! |
66 | | -//! fn main() { |
67 | | -//! let mut flags = FlagA | FlagB; |
68 | | -//! flags.clear(); |
69 | | -//! assert!(flags.is_empty()); |
70 | | -//! assert_eq!(format!("{}", flags).as_slice(), "hi!"); |
71 | | -//! } |
72 | | -//! ~~~ |
73 | | -//! |
74 | | -//! # Attributes |
75 | | -//! |
76 | | -//! Attributes can be attached to the generated `struct` by placing them |
77 | | -//! before the `flags` keyword. |
78 | | -//! |
79 | | -//! # Derived traits |
80 | | -//! |
81 | | -//! The `PartialEq` and `Clone` traits are automatically derived for the `struct` using |
82 | | -//! the `deriving` attribute. Additional traits can be derived by providing an |
83 | | -//! explicit `deriving` attribute on `flags`. |
84 | | -//! |
85 | | -//! # Operators |
86 | | -//! |
87 | | -//! The following operator traits are implemented for the generated `struct`: |
88 | | -//! |
89 | | -//! - `BitOr`: union |
90 | | -//! - `BitAnd`: intersection |
91 | | -//! - `Sub`: set difference |
92 | | -//! - `Not`: set complement |
93 | | -//! |
94 | | -//! # Methods |
95 | | -//! |
96 | | -//! The following methods are defined for the generated `struct`: |
97 | | -//! |
98 | | -//! - `empty`: an empty set of flags |
99 | | -//! - `all`: the set of all flags |
100 | | -//! - `bits`: the raw value of the flags currently stored |
101 | | -//! - `is_empty`: `true` if no flags are currently stored |
102 | | -//! - `is_all`: `true` if all flags are currently set |
103 | | -//! - `intersects`: `true` if there are flags common to both `self` and `other` |
104 | | -//! - `contains`: `true` all of the flags in `other` are contained within `self` |
105 | | -//! - `insert`: inserts the specified flags in-place |
106 | | -//! - `remove`: removes the specified flags in-place |
107 | | -
|
108 | 11 | #![experimental] |
109 | 12 | #![macro_escape] |
110 | 13 |
|
| 14 | +//! A typesafe bitmask flag generator. |
| 15 | +
|
| 16 | +/// The `bitflags!` macro generates a `struct` that holds a set of C-style |
| 17 | +/// bitmask flags. It is useful for creating typesafe wrappers for C APIs. |
| 18 | +/// |
| 19 | +/// The flags should only be defined for integer types, otherwise unexpected |
| 20 | +/// type errors may occur at compile time. |
| 21 | +/// |
| 22 | +/// # Example |
| 23 | +/// |
| 24 | +/// ~~~rust |
| 25 | +/// bitflags! { |
| 26 | +/// flags Flags: u32 { |
| 27 | +/// static FlagA = 0x00000001, |
| 28 | +/// static FlagB = 0x00000010, |
| 29 | +/// static FlagC = 0x00000100, |
| 30 | +/// static FlagABC = FlagA.bits |
| 31 | +/// | FlagB.bits |
| 32 | +/// | FlagC.bits, |
| 33 | +/// } |
| 34 | +/// } |
| 35 | +/// |
| 36 | +/// fn main() { |
| 37 | +/// let e1 = FlagA | FlagC; |
| 38 | +/// let e2 = FlagB | FlagC; |
| 39 | +/// assert!((e1 | e2) == FlagABC); // union |
| 40 | +/// assert!((e1 & e2) == FlagC); // intersection |
| 41 | +/// assert!((e1 - e2) == FlagA); // set difference |
| 42 | +/// assert!(!e2 == FlagA); // set complement |
| 43 | +/// } |
| 44 | +/// ~~~ |
| 45 | +/// |
| 46 | +/// The generated `struct`s can also be extended with type and trait implementations: |
| 47 | +/// |
| 48 | +/// ~~~rust |
| 49 | +/// use std::fmt; |
| 50 | +/// |
| 51 | +/// bitflags! { |
| 52 | +/// flags Flags: u32 { |
| 53 | +/// static FlagA = 0x00000001, |
| 54 | +/// static FlagB = 0x00000010, |
| 55 | +/// } |
| 56 | +/// } |
| 57 | +/// |
| 58 | +/// impl Flags { |
| 59 | +/// pub fn clear(&mut self) { |
| 60 | +/// self.bits = 0; // The `bits` field can be accessed from within the |
| 61 | +/// // same module where the `bitflags!` macro was invoked. |
| 62 | +/// } |
| 63 | +/// } |
| 64 | +/// |
| 65 | +/// impl fmt::Show for Flags { |
| 66 | +/// fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
| 67 | +/// write!(f, "hi!") |
| 68 | +/// } |
| 69 | +/// } |
| 70 | +/// |
| 71 | +/// fn main() { |
| 72 | +/// let mut flags = FlagA | FlagB; |
| 73 | +/// flags.clear(); |
| 74 | +/// assert!(flags.is_empty()); |
| 75 | +/// assert_eq!(format!("{}", flags).as_slice(), "hi!"); |
| 76 | +/// } |
| 77 | +/// ~~~ |
| 78 | +/// |
| 79 | +/// # Attributes |
| 80 | +/// |
| 81 | +/// Attributes can be attached to the generated `struct` by placing them |
| 82 | +/// before the `flags` keyword. |
| 83 | +/// |
| 84 | +/// # Derived traits |
| 85 | +/// |
| 86 | +/// The `PartialEq` and `Clone` traits are automatically derived for the `struct` using |
| 87 | +/// the `deriving` attribute. Additional traits can be derived by providing an |
| 88 | +/// explicit `deriving` attribute on `flags`. |
| 89 | +/// |
| 90 | +/// # Operators |
| 91 | +/// |
| 92 | +/// The following operator traits are implemented for the generated `struct`: |
| 93 | +/// |
| 94 | +/// - `BitOr`: union |
| 95 | +/// - `BitAnd`: intersection |
| 96 | +/// - `Sub`: set difference |
| 97 | +/// - `Not`: set complement |
| 98 | +/// |
| 99 | +/// # Methods |
| 100 | +/// |
| 101 | +/// The following methods are defined for the generated `struct`: |
| 102 | +/// |
| 103 | +/// - `empty`: an empty set of flags |
| 104 | +/// - `all`: the set of all flags |
| 105 | +/// - `bits`: the raw value of the flags currently stored |
| 106 | +/// - `is_empty`: `true` if no flags are currently stored |
| 107 | +/// - `is_all`: `true` if all flags are currently set |
| 108 | +/// - `intersects`: `true` if there are flags common to both `self` and `other` |
| 109 | +/// - `contains`: `true` all of the flags in `other` are contained within `self` |
| 110 | +/// - `insert`: inserts the specified flags in-place |
| 111 | +/// - `remove`: removes the specified flags in-place |
111 | 112 | #[macro_export] |
112 | | -macro_rules! bitflags( |
| 113 | +macro_rules! bitflags { |
113 | 114 | ($(#[$attr:meta])* flags $BitFlags:ident: $T:ty { |
114 | 115 | $($(#[$Flag_attr:meta])* static $Flag:ident = $value:expr),+ |
115 | | - }) => ( |
| 116 | + }) => { |
116 | 117 | #[deriving(PartialEq, Eq, Clone, PartialOrd, Ord, Hash)] |
117 | 118 | $(#[$attr])* |
118 | 119 | pub struct $BitFlags { |
@@ -215,25 +216,43 @@ macro_rules! bitflags( |
215 | 216 | $BitFlags { bits: !self.bits } & $BitFlags::all() |
216 | 217 | } |
217 | 218 | } |
218 | | - ) |
219 | | -) |
| 219 | + }; |
| 220 | + ($(#[$attr:meta])* flags $BitFlags:ident: $T:ty { |
| 221 | + $($(#[$Flag_attr:meta])* static $Flag:ident = $value:expr),+, |
| 222 | + }) => { |
| 223 | + bitflags! { |
| 224 | + $(#[$attr])* |
| 225 | + flags $BitFlags: u32 { |
| 226 | + $($(#[$Flag_attr])* static $Flag = $value),+ |
| 227 | + } |
| 228 | + } |
| 229 | + }; |
| 230 | +} |
220 | 231 |
|
221 | 232 | #[cfg(test)] |
222 | 233 | mod tests { |
223 | 234 | use hash; |
224 | 235 | use option::{Some, None}; |
225 | 236 | use ops::{BitOr, BitAnd, Sub, Not}; |
226 | 237 |
|
227 | | - bitflags!( |
| 238 | + bitflags! { |
| 239 | + #[doc = "> The first principle is that you must not fool yourself — and"] |
| 240 | + #[doc = "> you are the easiest person to fool."] |
| 241 | + #[doc = "> "] |
| 242 | + #[doc = "> - Richard Feynman"] |
228 | 243 | flags Flags: u32 { |
229 | 244 | static FlagA = 0x00000001, |
| 245 | + #[doc = "<pcwalton> macros are way better at generating code than trans is"] |
230 | 246 | static FlagB = 0x00000010, |
231 | 247 | static FlagC = 0x00000100, |
| 248 | + #[doc = "* cmr bed"] |
| 249 | + #[doc = "* strcat table"] |
| 250 | + #[doc = "<strcat> wait what?"] |
232 | 251 | static FlagABC = FlagA.bits |
233 | 252 | | FlagB.bits |
234 | | - | FlagC.bits |
| 253 | + | FlagC.bits, |
235 | 254 | } |
236 | | - ) |
| 255 | + } |
237 | 256 |
|
238 | 257 | #[test] |
239 | 258 | fn test_bits(){ |
|
0 commit comments