93
93
///
94
94
/// - `BitOr`: union
95
95
/// - `BitAnd`: intersection
96
+ /// - `BitXor`: toggle
96
97
/// - `Sub`: set difference
97
98
/// - `Not`: set complement
98
99
///
109
110
/// - `contains`: `true` all of the flags in `other` are contained within `self`
110
111
/// - `insert`: inserts the specified flags in-place
111
112
/// - `remove`: removes the specified flags in-place
113
+ /// - `toggle`: the specified flags will be inserted if not present, and removed
114
+ /// if they are.
112
115
#[ macro_export]
113
116
macro_rules! bitflags {
114
117
( $( #[ $attr: meta] ) * flags $BitFlags: ident: $T: ty {
@@ -184,6 +187,11 @@ macro_rules! bitflags {
184
187
pub fn remove( & mut self , other: $BitFlags) {
185
188
self . bits &= !other. bits;
186
189
}
190
+
191
+ /// Toggles the specified flags in-place.
192
+ pub fn toggle( & mut self , other: $BitFlags) {
193
+ self . bits ^= other. bits;
194
+ }
187
195
}
188
196
189
197
impl BitOr <$BitFlags, $BitFlags> for $BitFlags {
@@ -194,6 +202,14 @@ macro_rules! bitflags {
194
202
}
195
203
}
196
204
205
+ impl BitXor <$BitFlags, $BitFlags> for $BitFlags {
206
+ /// Returns the left flags, but with all the right flags toggled.
207
+ #[ inline]
208
+ fn bitxor( & self , other: & $BitFlags) -> $BitFlags {
209
+ $BitFlags { bits: self . bits ^ other. bits }
210
+ }
211
+ }
212
+
197
213
impl BitAnd <$BitFlags, $BitFlags> for $BitFlags {
198
214
/// Returns the intersection between the two sets of flags.
199
215
#[ inline]
@@ -234,7 +250,7 @@ macro_rules! bitflags {
234
250
mod tests {
235
251
use hash;
236
252
use option:: { Some , None } ;
237
- use ops:: { BitOr , BitAnd , Sub , Not } ;
253
+ use ops:: { BitOr , BitAnd , BitXor , Sub , Not } ;
238
254
239
255
bitflags ! {
240
256
#[ doc = "> The first principle is that you must not fool yourself — and" ]
@@ -358,10 +374,14 @@ mod tests {
358
374
fn test_operators ( ) {
359
375
let e1 = FlagA | FlagC ;
360
376
let e2 = FlagB | FlagC ;
361
- assert ! ( ( e1 | e2) == FlagABC ) ; // union
362
- assert ! ( ( e1 & e2) == FlagC ) ; // intersection
363
- assert ! ( ( e1 - e2) == FlagA ) ; // set difference
364
- assert ! ( !e2 == FlagA ) ; // set complement
377
+ assert ! ( ( e1 | e2) == FlagABC ) ; // union
378
+ assert ! ( ( e1 & e2) == FlagC ) ; // intersection
379
+ assert ! ( ( e1 - e2) == FlagA ) ; // set difference
380
+ assert ! ( !e2 == FlagA ) ; // set complement
381
+ assert ! ( e1 ^ e2 == FlagA | FlagB ) ; // toggle
382
+ let mut e3 = e1;
383
+ e3. toggle ( e2) ;
384
+ assert ! ( e3 == FlagA | FlagB ) ;
365
385
}
366
386
367
387
#[ test]
0 commit comments