|
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