@@ -635,3 +635,86 @@ pub struct False;
635635
636636// SAFETY: This is one of the only two implementations of `Bool`.
637637unsafe impl Bool for False { }
638+
639+ /// Helper macro to declare a bitfield style type. The type will automatically
640+ /// gain boolean operator implementations, as well as the `as_raw()` and `contains()`
641+ /// methods, Debug, Copy, Clone, and PartialEq implementations.
642+ ///
643+ /// Optionally, a default value can be specified with `= value` syntax, which
644+ /// will add a Default trait implementation.
645+ ///
646+ /// # Examples
647+ ///
648+ /// ```
649+ /// declare_flags_type! {
650+ /// /// Flags to be used for foo.
651+ /// pub struct FooFlags(u32);
652+ /// }
653+ ///
654+ /// declare_flags_type! {
655+ /// /// Flags to be used for bar.
656+ /// pub struct BarFlags(u32) = 0;
657+ /// }
658+ /// ```
659+ macro_rules! declare_flags_type (
660+ (
661+ $( #[ $outer: meta] ) *
662+ $v: vis struct $t: ident ( $base: ty ) ;
663+ $( $rest: tt) *
664+ ) => {
665+ $( #[ $outer] ) *
666+ #[ derive( Debug , Clone , Copy , PartialEq ) ]
667+ $v struct $t( $base) ;
668+
669+ impl $t {
670+ /// Get the raw representation of this flag.
671+ pub ( crate ) fn as_raw( self ) -> $base {
672+ self . 0
673+ }
674+
675+ /// Check whether `flags` is contained in `self`.
676+ pub fn contains( self , flags: Self ) -> bool {
677+ ( self & flags) == flags
678+ }
679+ }
680+
681+ impl core:: ops:: BitOr for $t {
682+ type Output = Self ;
683+ fn bitor( self , rhs: Self ) -> Self :: Output {
684+ Self ( self . 0 | rhs. 0 )
685+ }
686+ }
687+
688+ impl core:: ops:: BitAnd for $t {
689+ type Output = Self ;
690+ fn bitand( self , rhs: Self ) -> Self :: Output {
691+ Self ( self . 0 & rhs. 0 )
692+ }
693+ }
694+
695+ impl core:: ops:: Not for $t {
696+ type Output = Self ;
697+ fn not( self ) -> Self :: Output {
698+ Self ( !self . 0 )
699+ }
700+ }
701+ } ;
702+ (
703+ $( #[ $outer: meta] ) *
704+ $v: vis struct $t: ident ( $base: ty ) = $default: expr;
705+ $( $rest: tt) *
706+ ) => {
707+ declare_flags_type! {
708+ $( #[ $outer] ) *
709+ $v struct $t ( $base) ;
710+ $( $rest) *
711+ }
712+ impl Default for $t {
713+ fn default ( ) -> Self {
714+ Self ( $default)
715+ }
716+ }
717+ } ;
718+ ) ;
719+
720+ pub ( crate ) use declare_flags_type;
0 commit comments