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