bitflags_associated_constants/
lib.rs1#![feature(associated_consts)]
12
13#![no_std]
16
17#[cfg(test)]
18#[macro_use]
19extern crate std;
20
21#[allow(private_in_public)]
24#[doc(hidden)]
25pub use core as __core;
26
27#[macro_export]
186macro_rules! bitflags {
187 ($(#[$attr:meta])* pub flags $BitFlags:ident: $T:ty {
188 $($(#[$Flag_attr:meta])* const $Flag:ident = $value:expr),+
189 }) => {
190 #[derive(Copy, PartialEq, Eq, Clone, PartialOrd, Ord, Hash)]
191 $(#[$attr])*
192 pub struct $BitFlags {
193 bits: $T,
194 }
195
196 bitflags! {
197 @_impl flags $BitFlags: $T {
198 $($(#[$Flag_attr])* const $Flag = $value),+
199 }
200 }
201 };
202 ($(#[$attr:meta])* flags $BitFlags:ident: $T:ty {
203 $($(#[$Flag_attr:meta])* const $Flag:ident = $value:expr),+
204 }) => {
205 #[derive(Copy, PartialEq, Eq, Clone, PartialOrd, Ord, Hash)]
206 $(#[$attr])*
207 struct $BitFlags {
208 bits: $T,
209 }
210
211 bitflags! {
212 @_impl flags $BitFlags: $T {
213 $($(#[$Flag_attr])* const $Flag = $value),+
214 }
215 }
216 };
217 (@_impl flags $BitFlags:ident: $T:ty {
218 $($(#[$Flag_attr:meta])* const $Flag:ident = $value:expr),+
219 }) => {
220 impl $crate::__core::fmt::Debug for $BitFlags {
221 #[allow(unused_assignments)]
222 fn fmt(&self, f: &mut $crate::__core::fmt::Formatter) -> $crate::__core::fmt::Result {
223 trait DummyTrait {
231 $(const $Flag: $BitFlags = $BitFlags { bits: 0 };)+
235 };
236 struct DummyStruct;
237 impl DummyTrait for DummyStruct {
238 $($(#[$Flag_attr])* const $Flag: $BitFlags = $BitFlags { bits: $value };)+
242 };
243 let mut first = true;
244 $(
245 if DummyStruct::$Flag.bits != 0 && self.contains(DummyStruct::$Flag) {
247 if !first {
248 try!(f.write_str(" | "));
249 }
250 first = false;
251 try!(f.write_str(stringify!($Flag)));
252 }
253 )+
254 Ok(())
255 }
256 }
257
258 #[allow(dead_code)]
259 impl $BitFlags {
260 $($(#[$Flag_attr])* pub const $Flag: $BitFlags = $BitFlags { bits: $value };)+
261
262 #[inline]
264 pub const fn empty() -> $BitFlags {
265 $BitFlags { bits: 0 }
266 }
267
268 #[inline]
270 pub fn all() -> $BitFlags {
271 trait DummyTrait {
273 $(const $Flag: $BitFlags = $BitFlags { bits: 0 };)+
274 };
275 struct DummyStruct;
276 impl DummyTrait for DummyStruct {
277 $($(#[$Flag_attr])* const $Flag: $BitFlags = $BitFlags { bits: $value };)+
278 };
279 $BitFlags { bits: $(DummyStruct::$Flag.bits)|+ }
280 }
281
282 #[inline]
284 pub const fn bits(&self) -> $T {
285 self.bits
286 }
287
288 #[inline]
291 pub fn from_bits(bits: $T) -> $crate::__core::option::Option<$BitFlags> {
292 if (bits & !$BitFlags::all().bits()) == 0 {
293 $crate::__core::option::Option::Some($BitFlags { bits: bits })
294 } else {
295 $crate::__core::option::Option::None
296 }
297 }
298
299 #[inline]
302 pub fn from_bits_truncate(bits: $T) -> $BitFlags {
303 $BitFlags { bits: bits } & $BitFlags::all()
304 }
305
306 #[inline]
308 pub fn is_empty(&self) -> bool {
309 *self == $BitFlags::empty()
310 }
311
312 #[inline]
314 pub fn is_all(&self) -> bool {
315 *self == $BitFlags::all()
316 }
317
318 #[inline]
320 pub fn intersects(&self, other: $BitFlags) -> bool {
321 !(*self & other).is_empty()
322 }
323
324 #[inline]
326 pub fn contains(&self, other: $BitFlags) -> bool {
327 (*self & other) == other
328 }
329
330 #[inline]
332 pub fn insert(&mut self, other: $BitFlags) {
333 self.bits |= other.bits;
334 }
335
336 #[inline]
338 pub fn remove(&mut self, other: $BitFlags) {
339 self.bits &= !other.bits;
340 }
341
342 #[inline]
344 pub fn toggle(&mut self, other: $BitFlags) {
345 self.bits ^= other.bits;
346 }
347 }
348
349 impl $crate::__core::ops::BitOr for $BitFlags {
350 type Output = $BitFlags;
351
352 #[inline]
354 fn bitor(self, other: $BitFlags) -> $BitFlags {
355 $BitFlags { bits: self.bits | other.bits }
356 }
357 }
358
359 impl $crate::__core::ops::BitOrAssign for $BitFlags {
360
361 #[inline]
363 fn bitor_assign(&mut self, other: $BitFlags) {
364 self.bits |= other.bits;
365 }
366 }
367
368 impl $crate::__core::ops::BitXor for $BitFlags {
369 type Output = $BitFlags;
370
371 #[inline]
373 fn bitxor(self, other: $BitFlags) -> $BitFlags {
374 $BitFlags { bits: self.bits ^ other.bits }
375 }
376 }
377
378 impl $crate::__core::ops::BitXorAssign for $BitFlags {
379
380 #[inline]
382 fn bitxor_assign(&mut self, other: $BitFlags) {
383 self.bits ^= other.bits;
384 }
385 }
386
387 impl $crate::__core::ops::BitAnd for $BitFlags {
388 type Output = $BitFlags;
389
390 #[inline]
392 fn bitand(self, other: $BitFlags) -> $BitFlags {
393 $BitFlags { bits: self.bits & other.bits }
394 }
395 }
396
397 impl $crate::__core::ops::BitAndAssign for $BitFlags {
398
399 #[inline]
401 fn bitand_assign(&mut self, other: $BitFlags) {
402 self.bits &= other.bits;
403 }
404 }
405
406 impl $crate::__core::ops::Sub for $BitFlags {
407 type Output = $BitFlags;
408
409 #[inline]
411 fn sub(self, other: $BitFlags) -> $BitFlags {
412 $BitFlags { bits: self.bits & !other.bits }
413 }
414 }
415
416 impl $crate::__core::ops::SubAssign for $BitFlags {
417
418 #[inline]
420 fn sub_assign(&mut self, other: $BitFlags) {
421 self.bits &= !other.bits;
422 }
423 }
424
425 impl $crate::__core::ops::Not for $BitFlags {
426 type Output = $BitFlags;
427
428 #[inline]
430 fn not(self) -> $BitFlags {
431 $BitFlags { bits: !self.bits } & $BitFlags::all()
432 }
433 }
434
435 impl $crate::__core::iter::Extend<$BitFlags> for $BitFlags {
436 fn extend<T: $crate::__core::iter::IntoIterator<Item=$BitFlags>>(&mut self, iterator: T) {
437 for item in iterator {
438 self.insert(item)
439 }
440 }
441 }
442
443 impl $crate::__core::iter::FromIterator<$BitFlags> for $BitFlags {
444 fn from_iter<T: $crate::__core::iter::IntoIterator<Item=$BitFlags>>(iterator: T) -> $BitFlags {
445 let mut result = Self::empty();
446 result.extend(iterator);
447 result
448 }
449 }
450 };
451 ($(#[$attr:meta])* pub flags $BitFlags:ident: $T:ty {
452 $($(#[$Flag_attr:meta])* const $Flag:ident = $value:expr),+,
453 }) => {
454 bitflags! {
455 $(#[$attr])*
456 pub flags $BitFlags: $T {
457 $($(#[$Flag_attr])* const $Flag = $value),+
458 }
459 }
460 };
461 ($(#[$attr:meta])* flags $BitFlags:ident: $T:ty {
462 $($(#[$Flag_attr:meta])* const $Flag:ident = $value:expr),+,
463 }) => {
464 bitflags! {
465 $(#[$attr])*
466 flags $BitFlags: $T {
467 $($(#[$Flag_attr])* const $Flag = $value),+
468 }
469 }
470 };
471}
472
473#[cfg(test)]
474mod tests {
475 use std::hash::{SipHasher, Hash, Hasher};
476
477 bitflags! {
478 #[doc = "> The first principle is that you must not fool yourself — and"]
479 #[doc = "> you are the easiest person to fool."]
480 #[doc = "> "]
481 #[doc = "> - Richard Feynman"]
482 flags Flags: u32 {
483 const FLAG_A = 0b00000001,
484 #[doc = "<pcwalton> macros are way better at generating code than trans is"]
485 const FLAG_B = 0b00000010,
486 const FLAG_C = 0b00000100,
487 #[doc = "* cmr bed"]
488 #[doc = "* strcat table"]
489 #[doc = "<strcat> wait what?"]
490 const FLAG_ABC = Flags::FLAG_A.bits
491 | Flags::FLAG_B.bits
492 | Flags::FLAG_C.bits,
493 }
494 }
495
496 bitflags! {
497 flags CfgFlags: u32 {
498 #[cfg(windows)]
499 const CFG_A = 0b01,
500 #[cfg(unix)]
501 const CFG_B = 0b01,
502 #[cfg(windows)]
503 const CFG_C = CFG_A.bits | 0b10,
504 }
505 }
506
507 bitflags! {
508 flags AnotherSetOfFlags: i8 {
509 const ANOTHER_FLAG = -1_i8,
510 }
511 }
512
513 #[test]
514 fn test_bits() {
515 assert_eq!(Flags::empty().bits(), 0b00000000);
516 assert_eq!(Flags::FLAG_A.bits(), 0b00000001);
517 assert_eq!(Flags::FLAG_ABC.bits(), 0b00000111);
518
519 assert_eq!(AnotherSetOfFlags::empty().bits(), 0b00);
520 assert_eq!(AnotherSetOfFlags::ANOTHER_FLAG.bits(), !0_i8);
521 }
522
523 #[test]
524 fn test_from_bits() {
525 assert_eq!(Flags::from_bits(0), Some(Flags::empty()));
526 assert_eq!(Flags::from_bits(0b1), Some(Flags::FLAG_A));
527 assert_eq!(Flags::from_bits(0b10), Some(Flags::FLAG_B));
528 assert_eq!(Flags::from_bits(0b11), Some(Flags::FLAG_A | Flags::FLAG_B));
529 assert_eq!(Flags::from_bits(0b1000), None);
530
531 assert_eq!(AnotherSetOfFlags::from_bits(!0_i8), Some(AnotherSetOfFlags::ANOTHER_FLAG));
532 }
533
534 #[test]
535 fn test_from_bits_truncate() {
536 assert_eq!(Flags::from_bits_truncate(0), Flags::empty());
537 assert_eq!(Flags::from_bits_truncate(0b1), Flags::FLAG_A);
538 assert_eq!(Flags::from_bits_truncate(0b10), Flags::FLAG_B);
539 assert_eq!(Flags::from_bits_truncate(0b11), (Flags::FLAG_A | Flags::FLAG_B));
540 assert_eq!(Flags::from_bits_truncate(0b1000), Flags::empty());
541 assert_eq!(Flags::from_bits_truncate(0b1001), Flags::FLAG_A);
542
543 assert_eq!(AnotherSetOfFlags::from_bits_truncate(0_i8), AnotherSetOfFlags::empty());
544 }
545
546 #[test]
547 fn test_is_empty() {
548 assert!(Flags::empty().is_empty());
549 assert!(!Flags::FLAG_A.is_empty());
550 assert!(!Flags::FLAG_ABC.is_empty());
551
552 assert!(!AnotherSetOfFlags::ANOTHER_FLAG.is_empty());
553 }
554
555 #[test]
556 fn test_is_all() {
557 assert!(Flags::all().is_all());
558 assert!(!Flags::FLAG_A.is_all());
559 assert!(Flags::FLAG_ABC.is_all());
560
561 assert!(AnotherSetOfFlags::ANOTHER_FLAG.is_all());
562 }
563
564 #[test]
565 fn test_two_empties_do_not_intersect() {
566 let e1 = Flags::empty();
567 let e2 = Flags::empty();
568 assert!(!e1.intersects(e2));
569
570 assert!(AnotherSetOfFlags::ANOTHER_FLAG.intersects(AnotherSetOfFlags::ANOTHER_FLAG));
571 }
572
573 #[test]
574 fn test_empty_does_not_intersect_with_full() {
575 let e1 = Flags::empty();
576 let e2 = Flags::FLAG_ABC;
577 assert!(!e1.intersects(e2));
578 }
579
580 #[test]
581 fn test_disjoint_intersects() {
582 let e1 = Flags::FLAG_A;
583 let e2 = Flags::FLAG_B;
584 assert!(!e1.intersects(e2));
585 }
586
587 #[test]
588 fn test_overlapping_intersects() {
589 let e1 = Flags::FLAG_A;
590 let e2 = Flags::FLAG_A | Flags::FLAG_B;
591 assert!(e1.intersects(e2));
592 }
593
594 #[test]
595 fn test_contains() {
596 let e1 = Flags::FLAG_A;
597 let e2 = Flags::FLAG_A | Flags::FLAG_B;
598 assert!(!e1.contains(e2));
599 assert!(e2.contains(e1));
600 assert!(Flags::FLAG_ABC.contains(e2));
601
602 assert!(AnotherSetOfFlags::ANOTHER_FLAG.contains(AnotherSetOfFlags::ANOTHER_FLAG));
603 }
604
605 #[test]
606 fn test_insert() {
607 let mut e1 = Flags::FLAG_A;
608 let e2 = Flags::FLAG_A | Flags::FLAG_B;
609 e1.insert(e2);
610 assert_eq!(e1, e2);
611
612 let mut e3 = AnotherSetOfFlags::empty();
613 e3.insert(AnotherSetOfFlags::ANOTHER_FLAG);
614 assert_eq!(e3, AnotherSetOfFlags::ANOTHER_FLAG);
615 }
616
617 #[test]
618 fn test_remove() {
619 let mut e1 = Flags::FLAG_A | Flags::FLAG_B;
620 let e2 = Flags::FLAG_A | Flags::FLAG_C;
621 e1.remove(e2);
622 assert_eq!(e1, Flags::FLAG_B);
623
624 let mut e3 = AnotherSetOfFlags::ANOTHER_FLAG;
625 e3.remove(AnotherSetOfFlags::ANOTHER_FLAG);
626 assert_eq!(e3, AnotherSetOfFlags::empty());
627 }
628
629 #[test]
630 fn test_operators() {
631 let e1 = Flags::FLAG_A | Flags::FLAG_C;
632 let e2 = Flags::FLAG_B | Flags::FLAG_C;
633 assert_eq!((e1 | e2), Flags::FLAG_ABC); assert_eq!((e1 & e2), Flags::FLAG_C); assert_eq!((e1 - e2), Flags::FLAG_A); assert_eq!(!e2, Flags::FLAG_A); assert_eq!(e1 ^ e2, Flags::FLAG_A | Flags::FLAG_B); let mut e3 = e1;
639 e3.toggle(e2);
640 assert_eq!(e3, Flags::FLAG_A | Flags::FLAG_B);
641
642 let mut m4 = AnotherSetOfFlags::empty();
643 m4.toggle(AnotherSetOfFlags::empty());
644 assert_eq!(m4, AnotherSetOfFlags::empty());
645 }
646
647 #[test]
648 fn test_assignment_operators() {
649 let mut m1 = Flags::empty();
650 let e1 = Flags::FLAG_A | Flags::FLAG_C;
651 m1 |= Flags::FLAG_A;
653 assert_eq!(m1, Flags::FLAG_A);
654 m1 &= e1;
656 assert_eq!(m1, Flags::FLAG_A);
657 m1 -= m1;
659 assert_eq!(m1, Flags::empty());
660 m1 ^= e1;
662 assert_eq!(m1, e1);
663 }
664
665 #[test]
666 fn test_extend() {
667 let mut flags;
668
669 flags = Flags::empty();
670 flags.extend([].iter().cloned());
671 assert_eq!(flags, Flags::empty());
672
673 flags = Flags::empty();
674 flags.extend([Flags::FLAG_A, Flags::FLAG_B].iter().cloned());
675 assert_eq!(flags, Flags::FLAG_A | Flags::FLAG_B);
676
677 flags = Flags::FLAG_A;
678 flags.extend([Flags::FLAG_A, Flags::FLAG_B].iter().cloned());
679 assert_eq!(flags, Flags::FLAG_A | Flags::FLAG_B);
680
681 flags = Flags::FLAG_B;
682 flags.extend([Flags::FLAG_A, Flags::FLAG_ABC].iter().cloned());
683 assert_eq!(flags, Flags::FLAG_ABC);
684 }
685
686 #[test]
687 fn test_from_iterator() {
688 assert_eq!([].iter().cloned().collect::<Flags>(), Flags::empty());
689 assert_eq!([Flags::FLAG_A, Flags::FLAG_B].iter().cloned().collect::<Flags>(),
690 Flags::FLAG_A | Flags::FLAG_B);
691 assert_eq!([Flags::FLAG_A, Flags::FLAG_ABC].iter().cloned().collect::<Flags>(),
692 Flags::FLAG_ABC);
693 }
694
695 #[test]
696 fn test_lt() {
697 let mut a = Flags::empty();
698 let mut b = Flags::empty();
699
700 assert!(!(a < b) && !(b < a));
701 b = Flags::FLAG_B;
702 assert!(a < b);
703 a = Flags::FLAG_C;
704 assert!(!(a < b) && b < a);
705 b = Flags::FLAG_C | Flags::FLAG_B;
706 assert!(a < b);
707 }
708
709 #[test]
710 fn test_ord() {
711 let mut a = Flags::empty();
712 let mut b = Flags::empty();
713
714 assert!(a <= b && a >= b);
715 a = Flags::FLAG_A;
716 assert!(a > b && a >= b);
717 assert!(b < a && b <= a);
718 b = Flags::FLAG_B;
719 assert!(b > a && b >= a);
720 assert!(a < b && a <= b);
721 }
722
723 fn hash<T: Hash>(t: &T) -> u64 {
724 let mut s = SipHasher::new_with_keys(0, 0);
725 t.hash(&mut s);
726 s.finish()
727 }
728
729 #[test]
730 fn test_hash() {
731 let mut x = Flags::empty();
732 let mut y = Flags::empty();
733 assert_eq!(hash(&x), hash(&y));
734 x = Flags::all();
735 y = Flags::FLAG_ABC;
736 assert_eq!(hash(&x), hash(&y));
737 }
738
739 #[test]
740 fn test_debug() {
741 assert_eq!(format!("{:?}", Flags::FLAG_A | Flags::FLAG_B),
742 "FLAG_A | FLAG_B");
743 assert_eq!(format!("{:?}", Flags::FLAG_ABC),
744 "FLAG_A | FLAG_B | FLAG_C | FLAG_ABC");
745 }
746
747 mod submodule {
748 bitflags! {
749 pub flags PublicFlags: i8 {
750 const FLAG_X = 0,
751 }
752 }
753 bitflags! {
754 flags PrivateFlags: i8 {
755 const FLAG_Y = 0,
756 }
757 }
758
759 #[test]
760 fn test_private() {
761 let _ = PrivateFlags::FLAG_Y;
762 }
763 }
764
765 #[test]
766 fn test_public() {
767 let _ = submodule::PublicFlags::FLAG_X;
768 }
769}