@@ -602,3 +602,86 @@ pub type NotThreadSafe = PhantomData<*mut ()>;
602602/// [`NotThreadSafe`]: type@NotThreadSafe
603603#[ allow( non_upper_case_globals) ]
604604pub const NotThreadSafe : NotThreadSafe = PhantomData ;
605+
606+ /// Helper macro to declare a bitfield style type. The type will automatically
607+ /// gain boolean operator implementations, as well as the `as_raw()` and `contains()`
608+ /// methods, Debug, Copy, Clone, and PartialEq implementations.
609+ ///
610+ /// Optionally, a default value can be specified with `= value` syntax, which
611+ /// will add a Default trait implementation.
612+ ///
613+ /// # Examples
614+ ///
615+ /// ```
616+ /// declare_flags_type! {
617+ /// /// Flags to be used for foo.
618+ /// pub struct FooFlags(u32);
619+ /// }
620+ ///
621+ /// declare_flags_type! {
622+ /// /// Flags to be used for bar.
623+ /// pub struct BarFlags(u32) = 0;
624+ /// }
625+ /// ```
626+ macro_rules! declare_flags_type (
627+ (
628+ $( #[ $outer: meta] ) *
629+ $v: vis struct $t: ident ( $base: ty ) ;
630+ $( $rest: tt) *
631+ ) => {
632+ $( #[ $outer] ) *
633+ #[ derive( Debug , Clone , Copy , PartialEq ) ]
634+ $v struct $t( $base) ;
635+
636+ impl $t {
637+ /// Get the raw representation of this flag.
638+ pub ( crate ) fn as_raw( self ) -> $base {
639+ self . 0
640+ }
641+
642+ /// Check whether `flags` is contained in `self`.
643+ pub fn contains( self , flags: Self ) -> bool {
644+ ( self & flags) == flags
645+ }
646+ }
647+
648+ impl core:: ops:: BitOr for $t {
649+ type Output = Self ;
650+ fn bitor( self , rhs: Self ) -> Self :: Output {
651+ Self ( self . 0 | rhs. 0 )
652+ }
653+ }
654+
655+ impl core:: ops:: BitAnd for $t {
656+ type Output = Self ;
657+ fn bitand( self , rhs: Self ) -> Self :: Output {
658+ Self ( self . 0 & rhs. 0 )
659+ }
660+ }
661+
662+ impl core:: ops:: Not for $t {
663+ type Output = Self ;
664+ fn not( self ) -> Self :: Output {
665+ Self ( !self . 0 )
666+ }
667+ }
668+ } ;
669+ (
670+ $( #[ $outer: meta] ) *
671+ $v: vis struct $t: ident ( $base: ty ) = $default: expr;
672+ $( $rest: tt) *
673+ ) => {
674+ declare_flags_type! {
675+ $( #[ $outer] ) *
676+ $v struct $t ( $base) ;
677+ $( $rest) *
678+ }
679+ impl Default for $t {
680+ fn default ( ) -> Self {
681+ Self ( $default)
682+ }
683+ }
684+ } ;
685+ ) ;
686+
687+ pub ( crate ) use declare_flags_type;
0 commit comments