@@ -443,3 +443,86 @@ pub type NotThreadSafe = PhantomData<*mut ()>;
443443/// [`NotThreadSafe`]: type@NotThreadSafe
444444#[ allow( non_upper_case_globals) ]
445445pub const NotThreadSafe : NotThreadSafe = PhantomData ;
446+
447+ /// Helper macro to declare a bitfield style type. The type will automatically
448+ /// gain boolean operator implementations, as well as the `as_raw()` and `contains()`
449+ /// methods, Debug, Copy, Clone, and PartialEq implementations.
450+ ///
451+ /// Optionally, a default value can be specified with `= value` syntax, which
452+ /// will add a Default trait implementation.
453+ ///
454+ /// # Examples
455+ ///
456+ /// ```
457+ /// declare_flags_type! {
458+ /// /// Flags to be used for foo.
459+ /// pub struct FooFlags(u32);
460+ /// }
461+ ///
462+ /// declare_flags_type! {
463+ /// /// Flags to be used for bar.
464+ /// pub struct BarFlags(u32) = 0;
465+ /// }
466+ /// ```
467+ macro_rules! declare_flags_type (
468+ (
469+ $( #[ $outer: meta] ) *
470+ $v: vis struct $t: ident ( $base: ty ) ;
471+ $( $rest: tt) *
472+ ) => {
473+ $( #[ $outer] ) *
474+ #[ derive( Debug , Clone , Copy , PartialEq ) ]
475+ $v struct $t( $base) ;
476+
477+ impl $t {
478+ /// Get the raw representation of this flag.
479+ pub ( crate ) fn as_raw( self ) -> $base {
480+ self . 0
481+ }
482+
483+ /// Check whether `flags` is contained in `self`.
484+ pub fn contains( self , flags: Self ) -> bool {
485+ ( self & flags) == flags
486+ }
487+ }
488+
489+ impl core:: ops:: BitOr for $t {
490+ type Output = Self ;
491+ fn bitor( self , rhs: Self ) -> Self :: Output {
492+ Self ( self . 0 | rhs. 0 )
493+ }
494+ }
495+
496+ impl core:: ops:: BitAnd for $t {
497+ type Output = Self ;
498+ fn bitand( self , rhs: Self ) -> Self :: Output {
499+ Self ( self . 0 & rhs. 0 )
500+ }
501+ }
502+
503+ impl core:: ops:: Not for $t {
504+ type Output = Self ;
505+ fn not( self ) -> Self :: Output {
506+ Self ( !self . 0 )
507+ }
508+ }
509+ } ;
510+ (
511+ $( #[ $outer: meta] ) *
512+ $v: vis struct $t: ident ( $base: ty ) = $default: expr;
513+ $( $rest: tt) *
514+ ) => {
515+ declare_flags_type! {
516+ $( #[ $outer] ) *
517+ $v struct $t ( $base) ;
518+ $( $rest) *
519+ }
520+ impl Default for $t {
521+ fn default ( ) -> Self {
522+ Self ( $default)
523+ }
524+ }
525+ } ;
526+ ) ;
527+
528+ pub ( crate ) use declare_flags_type;
0 commit comments