bitflags/
lib.rs

1// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2// file at the top-level directory of this distribution and at
3// http://rust-lang.org/COPYRIGHT.
4//
5// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8// option. This file may not be copied, modified, or distributed
9// except according to those terms.
10
11/*!
12Generate types for C-style flags with ergonomic APIs.
13
14# Getting started
15
16Add `bitflags` to your `Cargo.toml`:
17
18```toml
19[dependencies.bitflags]
20version = "2.4.1"
21```
22
23## Generating flags types
24
25Use the [`bitflags`] macro to generate flags types:
26
27```rust
28use bitflags::bitflags;
29
30bitflags! {
31    pub struct Flags: u32 {
32        const A = 0b00000001;
33        const B = 0b00000010;
34        const C = 0b00000100;
35    }
36}
37```
38
39See the docs for the `bitflags` macro for the full syntax.
40
41Also see the [`example_generated`] module for an example of what the `bitflags` macro generates for a flags type.
42
43### Externally defined flags
44
45If you're generating flags types for an external source, such as a C API, you can define
46an extra unnamed flag as a mask of all bits the external source may ever set. Usually this would be all bits (`!0`):
47
48```rust
49# use bitflags::bitflags;
50bitflags! {
51    pub struct Flags: u32 {
52        const A = 0b00000001;
53        const B = 0b00000010;
54        const C = 0b00000100;
55
56        // The source may set any bits
57        const _ = !0;
58    }
59}
60```
61
62Why should you do this? Generated methods like `all` and truncating operators like `!` only consider
63bits in defined flags. Adding an unnamed flag makes those methods consider additional bits,
64without generating additional constants for them. It helps compatibility when the external source
65may start setting additional bits at any time. The [known and unknown bits](#known-and-unknown-bits)
66section has more details on this behavior.
67
68### Custom derives
69
70You can derive some traits on generated flags types if you enable Cargo features. The following
71libraries are currently supported:
72
73- `serde`: Support `#[derive(Serialize, Deserialize)]`, using text for human-readable formats,
74and a raw number for binary formats.
75- `arbitrary`: Support `#[derive(Arbitrary)]`, only generating flags values with known bits.
76- `bytemuck`: Support `#[derive(Pod, Zeroable)]`, for casting between flags values and their
77underlying bits values.
78
79You can also define your own flags type outside of the [`bitflags`] macro and then use it to generate methods.
80This can be useful if you need a custom `#[derive]` attribute for a library that `bitflags` doesn't
81natively support:
82
83```rust
84# use std::fmt::Debug as SomeTrait;
85# use bitflags::bitflags;
86#[derive(SomeTrait)]
87pub struct Flags(u32);
88
89bitflags! {
90    impl Flags: u32 {
91        const A = 0b00000001;
92        const B = 0b00000010;
93        const C = 0b00000100;
94    }
95}
96```
97
98### Adding custom methods
99
100The [`bitflags`] macro supports attributes on generated flags types within the macro itself, while
101`impl` blocks can be added outside of it:
102
103```rust
104# use bitflags::bitflags;
105bitflags! {
106    // Attributes can be applied to flags types
107    #[repr(transparent)]
108    #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
109    pub struct Flags: u32 {
110        const A = 0b00000001;
111        const B = 0b00000010;
112        const C = 0b00000100;
113    }
114}
115
116// Impl blocks can be added to flags types
117impl Flags {
118    pub fn as_u64(&self) -> u64 {
119        self.bits() as u64
120    }
121}
122```
123
124## Working with flags values
125
126Use generated constants and standard bitwise operators to interact with flags values:
127
128```rust
129# use bitflags::bitflags;
130# bitflags! {
131#     #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
132#     pub struct Flags: u32 {
133#         const A = 0b00000001;
134#         const B = 0b00000010;
135#         const C = 0b00000100;
136#     }
137# }
138// union
139let ab = Flags::A | Flags::B;
140
141// intersection
142let a = ab & Flags::A;
143
144// difference
145let b = ab - Flags::A;
146
147// complement
148let c = !ab;
149```
150
151See the docs for the [`Flags`] trait for more details on operators and how they behave.
152
153# Formatting and parsing
154
155`bitflags` defines a text format that can be used to convert any flags value to and from strings.
156
157See the [`parser`] module for more details.
158
159# Specification
160
161The terminology and behavior of generated flags types is
162[specified in the source repository](https://github.com/bitflags/bitflags/blob/main/spec.md).
163Details are repeated in these docs where appropriate, but is exhaustively listed in the spec. Some
164things are worth calling out explicitly here.
165
166## Flags types, flags values, flags
167
168The spec and these docs use consistent terminology to refer to things in the bitflags domain:
169
170- **Bits type**: A type that defines a fixed number of bits at specific locations.
171- **Flag**: A set of bits in a bits type that may have a unique name.
172- **Flags type**: A set of defined flags over a specific bits type.
173- **Flags value**: An instance of a flags type using its specific bits value for storage.
174
175```
176# use bitflags::bitflags;
177bitflags! {
178    struct FlagsType: u8 {
179//                    -- Bits type
180//         --------- Flags type
181        const A = 1;
182//            ----- Flag
183    }
184}
185
186let flag = FlagsType::A;
187//  ---- Flags value
188```
189
190## Known and unknown bits
191
192Any bits in a flag you define are called _known bits_. Any other bits are _unknown bits_.
193In the following flags type:
194
195```
196# use bitflags::bitflags;
197bitflags! {
198    struct Flags: u8 {
199        const A = 1;
200        const B = 1 << 1;
201        const C = 1 << 2;
202    }
203}
204```
205
206The known bits are `0b0000_0111` and the unknown bits are `0b1111_1000`.
207
208`bitflags` doesn't guarantee that a flags value will only ever have known bits set, but some operators
209will unset any unknown bits they encounter. In a future version of `bitflags`, all operators will
210unset unknown bits.
211
212If you're using `bitflags` for flags types defined externally, such as from C, you probably want all
213bits to be considered known, in case that external source changes. You can do this using an unnamed
214flag, as described in [externally defined flags](#externally-defined-flags).
215
216## Zero-bit flags
217
218Flags with no bits set should be avoided because they interact strangely with [`Flags::contains`]
219and [`Flags::intersects`]. A zero-bit flag is always contained, but is never intersected. The
220names of zero-bit flags can be parsed, but are never formatted.
221
222## Multi-bit flags
223
224Flags that set multiple bits should be avoided unless each bit is also in a single-bit flag.
225Take the following flags type as an example:
226
227```
228# use bitflags::bitflags;
229bitflags! {
230    struct Flags: u8 {
231        const A = 1;
232        const B = 1 | 1 << 1;
233    }
234}
235```
236
237The result of `Flags::A ^ Flags::B` is `0b0000_0010`, which doesn't correspond to either
238`Flags::A` or `Flags::B` even though it's still a known bit.
239*/
240
241#![cfg_attr(not(any(feature = "std", test)), no_std)]
242#![cfg_attr(not(test), forbid(unsafe_code))]
243#![cfg_attr(test, allow(mixed_script_confusables))]
244
245#[doc(inline)]
246pub use traits::{Bits, Flag, Flags};
247
248pub mod iter;
249pub mod parser;
250
251mod traits;
252
253#[doc(hidden)]
254pub mod __private {
255    pub use crate::{external::__private::*, traits::__private::*};
256
257    pub use core;
258}
259
260#[allow(unused_imports)]
261pub use external::*;
262
263#[allow(deprecated)]
264pub use traits::BitFlags;
265
266/*
267How does the bitflags crate work?
268
269This library generates a `struct` in the end-user's crate with a bunch of constants on it that represent flags.
270The difference between `bitflags` and a lot of other libraries is that we don't actually control the generated `struct` in the end.
271It's part of the end-user's crate, so it belongs to them. That makes it difficult to extend `bitflags` with new functionality
272because we could end up breaking valid code that was already written.
273
274Our solution is to split the type we generate into two: the public struct owned by the end-user, and an internal struct owned by `bitflags` (us).
275To give you an example, let's say we had a crate that called `bitflags!`:
276
277```rust
278bitflags! {
279    pub struct MyFlags: u32 {
280        const A = 1;
281        const B = 2;
282    }
283}
284```
285
286What they'd end up with looks something like this:
287
288```rust
289pub struct MyFlags(<MyFlags as PublicFlags>::InternalBitFlags);
290
291const _: () = {
292    #[repr(transparent)]
293    #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
294    pub struct MyInternalBitFlags {
295        bits: u32,
296    }
297
298    impl PublicFlags for MyFlags {
299        type Internal = InternalBitFlags;
300    }
301};
302```
303
304If we want to expose something like a new trait impl for generated flags types, we add it to our generated `MyInternalBitFlags`,
305and let `#[derive]` on `MyFlags` pick up that implementation, if an end-user chooses to add one.
306
307The public API is generated in the `__impl_public_flags!` macro, and the internal API is generated in
308the `__impl_internal_flags!` macro.
309
310The macros are split into 3 modules:
311
312- `public`: where the user-facing flags types are generated.
313- `internal`: where the `bitflags`-facing flags types are generated.
314- `external`: where external library traits are implemented conditionally.
315*/
316
317/**
318Generate a flags type.
319
320# `struct` mode
321
322A declaration that begins with `$vis struct` will generate a `struct` for a flags type, along with
323methods and trait implementations for it. The body of the declaration defines flags as constants,
324where each constant is a flags value of the generated flags type.
325
326## Examples
327
328Generate a flags type using `u8` as the bits type:
329
330```
331# use bitflags::bitflags;
332bitflags! {
333    struct Flags: u8 {
334        const A = 1;
335        const B = 1 << 1;
336        const C = 0b0000_0100;
337    }
338}
339```
340
341Flags types are private by default and accept standard visibility modifiers. Flags themselves
342are always public:
343
344```
345# use bitflags::bitflags;
346bitflags! {
347    pub struct Flags: u8 {
348        // Constants are always `pub`
349        const A = 1;
350    }
351}
352```
353
354Flags may refer to other flags using their [`Flags::bits`] value:
355
356```
357# use bitflags::bitflags;
358bitflags! {
359    struct Flags: u8 {
360        const A = 1;
361        const B = 1 << 1;
362        const AB = Flags::A.bits() | Flags::B.bits();
363    }
364}
365```
366
367A single `bitflags` invocation may include zero or more flags type declarations:
368
369```
370# use bitflags::bitflags;
371bitflags! {}
372
373bitflags! {
374    struct Flags1: u8 {
375        const A = 1;
376    }
377
378    struct Flags2: u8 {
379        const A = 1;
380    }
381}
382```
383
384# `impl` mode
385
386A declaration that begins with `impl` will only generate methods and trait implementations for the
387`struct` defined outside of the `bitflags` macro.
388
389The struct itself must be a newtype using the bits type as its field.
390
391The syntax for `impl` mode is identical to `struct` mode besides the starting token.
392
393## Examples
394
395Implement flags methods and traits for a custom flags type using `u8` as its underlying bits type:
396
397```
398# use bitflags::bitflags;
399struct Flags(u8);
400
401bitflags! {
402    impl Flags: u8 {
403        const A = 1;
404        const B = 1 << 1;
405        const C = 0b0000_0100;
406    }
407}
408```
409
410# Named and unnamed flags
411
412Constants in the body of a declaration are flags. The identifier of the constant is the name of
413the flag. If the identifier is `_`, then the flag is unnamed. Unnamed flags don't appear in the
414generated API, but affect how bits are truncated.
415
416## Examples
417
418Adding an unnamed flag that makes all bits known:
419
420```
421# use bitflags::bitflags;
422bitflags! {
423    struct Flags: u8 {
424        const A = 1;
425        const B = 1 << 1;
426
427        const _ = !0;
428    }
429}
430```
431
432Flags types may define multiple unnamed flags:
433
434```
435# use bitflags::bitflags;
436bitflags! {
437    struct Flags: u8 {
438        const _ = 1;
439        const _ = 1 << 1;
440    }
441}
442```
443*/
444#[macro_export(local_inner_macros)]
445macro_rules! bitflags {
446    (
447        $(#[$outer:meta])*
448        $vis:vis struct $BitFlags:ident: $T:ty {
449            $(
450                $(#[$inner:ident $($args:tt)*])*
451                const $Flag:tt = $value:expr;
452            )*
453        }
454
455        $($t:tt)*
456    ) => {
457        // Declared in the scope of the `bitflags!` call
458        // This type appears in the end-user's API
459        __declare_public_bitflags! {
460            $(#[$outer])*
461            $vis struct $BitFlags
462        }
463
464        // Workaround for: https://github.com/bitflags/bitflags/issues/320
465        __impl_public_bitflags_consts! {
466            $BitFlags: $T {
467                $(
468                    $(#[$inner $($args)*])*
469                    const $Flag = $value;
470                )*
471            }
472        }
473
474        #[allow(
475            dead_code,
476            deprecated,
477            unused_doc_comments,
478            unused_attributes,
479            unused_mut,
480            unused_imports,
481            non_upper_case_globals,
482            clippy::assign_op_pattern,
483            clippy::indexing_slicing,
484            clippy::same_name_method,
485            clippy::iter_without_into_iter,
486        )]
487        const _: () = {
488            // Declared in a "hidden" scope that can't be reached directly
489            // These types don't appear in the end-user's API
490            __declare_internal_bitflags! {
491                $vis struct InternalBitFlags: $T
492            }
493
494            __impl_internal_bitflags! {
495                InternalBitFlags: $T, $BitFlags {
496                    $(
497                        $(#[$inner $($args)*])*
498                        const $Flag = $value;
499                    )*
500                }
501            }
502
503            // This is where new library trait implementations can be added
504            __impl_external_bitflags! {
505                InternalBitFlags: $T, $BitFlags {
506                    $(
507                        $(#[$inner $($args)*])*
508                        const $Flag;
509                    )*
510                }
511            }
512
513            __impl_public_bitflags_forward! {
514                $BitFlags: $T, InternalBitFlags
515            }
516
517            __impl_public_bitflags_ops! {
518                $BitFlags
519            }
520
521            __impl_public_bitflags_iter! {
522                $BitFlags: $T, $BitFlags
523            }
524        };
525
526        bitflags! {
527            $($t)*
528        }
529    };
530    (
531        impl $BitFlags:ident: $T:ty {
532            $(
533                $(#[$inner:ident $($args:tt)*])*
534                const $Flag:tt = $value:expr;
535            )*
536        }
537
538        $($t:tt)*
539    ) => {
540        __impl_public_bitflags_consts! {
541            $BitFlags: $T {
542                $(
543                    $(#[$inner $($args)*])*
544                    const $Flag = $value;
545                )*
546            }
547        }
548
549        #[allow(
550            dead_code,
551            deprecated,
552            unused_doc_comments,
553            unused_attributes,
554            unused_mut,
555            unused_imports,
556            non_upper_case_globals,
557            clippy::assign_op_pattern,
558            clippy::iter_without_into_iter,
559        )]
560        const _: () = {
561            __impl_public_bitflags! {
562                $BitFlags: $T, $BitFlags {
563                    $(
564                        $(#[$inner $($args)*])*
565                        const $Flag = $value;
566                    )*
567                }
568            }
569
570            __impl_public_bitflags_ops! {
571                $BitFlags
572            }
573
574            __impl_public_bitflags_iter! {
575                $BitFlags: $T, $BitFlags
576            }
577        };
578
579        bitflags! {
580            $($t)*
581        }
582    };
583    () => {};
584}
585
586/// Implement functions on bitflags types.
587///
588/// We need to be careful about adding new methods and trait implementations here because they
589/// could conflict with items added by the end-user.
590#[macro_export(local_inner_macros)]
591#[doc(hidden)]
592macro_rules! __impl_bitflags {
593    (
594        $PublicBitFlags:ident: $T:ty {
595            fn empty() $empty:block
596            fn all() $all:block
597            fn bits($bits0:ident) $bits:block
598            fn from_bits($from_bits0:ident) $from_bits:block
599            fn from_bits_truncate($from_bits_truncate0:ident) $from_bits_truncate:block
600            fn from_bits_retain($from_bits_retain0:ident) $from_bits_retain:block
601            fn from_name($from_name0:ident) $from_name:block
602            fn is_empty($is_empty0:ident) $is_empty:block
603            fn is_all($is_all0:ident) $is_all:block
604            fn intersects($intersects0:ident, $intersects1:ident) $intersects:block
605            fn contains($contains0:ident, $contains1:ident) $contains:block
606            fn insert($insert0:ident, $insert1:ident) $insert:block
607            fn remove($remove0:ident, $remove1:ident) $remove:block
608            fn toggle($toggle0:ident, $toggle1:ident) $toggle:block
609            fn set($set0:ident, $set1:ident, $set2:ident) $set:block
610            fn intersection($intersection0:ident, $intersection1:ident) $intersection:block
611            fn union($union0:ident, $union1:ident) $union:block
612            fn difference($difference0:ident, $difference1:ident) $difference:block
613            fn symmetric_difference($symmetric_difference0:ident, $symmetric_difference1:ident) $symmetric_difference:block
614            fn complement($complement0:ident) $complement:block
615        }
616    ) => {
617        #[allow(dead_code, deprecated, unused_attributes)]
618        impl $PublicBitFlags {
619            /// Get a flags value with all bits unset.
620            #[inline]
621            pub const fn empty() -> Self {
622                $empty
623            }
624
625            /// Get a flags value with all known bits set.
626            #[inline]
627            pub const fn all() -> Self {
628                $all
629            }
630
631            /// Get the underlying bits value.
632            ///
633            /// The returned value is exactly the bits set in this flags value.
634            #[inline]
635            pub const fn bits(&self) -> $T {
636                let $bits0 = self;
637                $bits
638            }
639
640            /// Convert from a bits value.
641            ///
642            /// This method will return `None` if any unknown bits are set.
643            #[inline]
644            pub const fn from_bits(bits: $T) -> $crate::__private::core::option::Option<Self> {
645                let $from_bits0 = bits;
646                $from_bits
647            }
648
649            /// Convert from a bits value, unsetting any unknown bits.
650            #[inline]
651            pub const fn from_bits_truncate(bits: $T) -> Self {
652                let $from_bits_truncate0 = bits;
653                $from_bits_truncate
654            }
655
656            /// Convert from a bits value exactly.
657            #[inline]
658            pub const fn from_bits_retain(bits: $T) -> Self {
659                let $from_bits_retain0 = bits;
660                $from_bits_retain
661            }
662
663            /// Get a flags value with the bits of a flag with the given name set.
664            ///
665            /// This method will return `None` if `name` is empty or doesn't
666            /// correspond to any named flag.
667            #[inline]
668            pub fn from_name(name: &str) -> $crate::__private::core::option::Option<Self> {
669                let $from_name0 = name;
670                $from_name
671            }
672
673            /// Whether all bits in this flags value are unset.
674            #[inline]
675            pub const fn is_empty(&self) -> bool {
676                let $is_empty0 = self;
677                $is_empty
678            }
679
680            /// Whether all known bits in this flags value are set.
681            #[inline]
682            pub const fn is_all(&self) -> bool {
683                let $is_all0 = self;
684                $is_all
685            }
686
687            /// Whether any set bits in a source flags value are also set in a target flags value.
688            #[inline]
689            pub const fn intersects(&self, other: Self) -> bool {
690                let $intersects0 = self;
691                let $intersects1 = other;
692                $intersects
693            }
694
695            /// Whether all set bits in a source flags value are also set in a target flags value.
696            #[inline]
697            pub const fn contains(&self, other: Self) -> bool {
698                let $contains0 = self;
699                let $contains1 = other;
700                $contains
701            }
702
703            /// The bitwise or (`|`) of the bits in two flags values.
704            #[inline]
705            pub fn insert(&mut self, other: Self) {
706                let $insert0 = self;
707                let $insert1 = other;
708                $insert
709            }
710
711            /// The intersection of a source flags value with the complement of a target flags value (`&!`).
712            ///
713            /// This method is not equivalent to `self & !other` when `other` has unknown bits set.
714            /// `remove` won't truncate `other`, but the `!` operator will.
715            #[inline]
716            pub fn remove(&mut self, other: Self) {
717                let $remove0 = self;
718                let $remove1 = other;
719                $remove
720            }
721
722            /// The bitwise exclusive-or (`^`) of the bits in two flags values.
723            #[inline]
724            pub fn toggle(&mut self, other: Self) {
725                let $toggle0 = self;
726                let $toggle1 = other;
727                $toggle
728            }
729
730            /// Call `insert` when `value` is `true` or `remove` when `value` is `false`.
731            #[inline]
732            pub fn set(&mut self, other: Self, value: bool) {
733                let $set0 = self;
734                let $set1 = other;
735                let $set2 = value;
736                $set
737            }
738
739            /// The bitwise and (`&`) of the bits in two flags values.
740            #[inline]
741            #[must_use]
742            pub const fn intersection(self, other: Self) -> Self {
743                let $intersection0 = self;
744                let $intersection1 = other;
745                $intersection
746            }
747
748            /// The bitwise or (`|`) of the bits in two flags values.
749            #[inline]
750            #[must_use]
751            pub const fn union(self, other: Self) -> Self {
752                let $union0 = self;
753                let $union1 = other;
754                $union
755            }
756
757            /// The intersection of a source flags value with the complement of a target flags value (`&!`).
758            ///
759            /// This method is not equivalent to `self & !other` when `other` has unknown bits set.
760            /// `difference` won't truncate `other`, but the `!` operator will.
761            #[inline]
762            #[must_use]
763            pub const fn difference(self, other: Self) -> Self {
764                let $difference0 = self;
765                let $difference1 = other;
766                $difference
767            }
768
769            /// The bitwise exclusive-or (`^`) of the bits in two flags values.
770            #[inline]
771            #[must_use]
772            pub const fn symmetric_difference(self, other: Self) -> Self {
773                let $symmetric_difference0 = self;
774                let $symmetric_difference1 = other;
775                $symmetric_difference
776            }
777
778            /// The bitwise negation (`!`) of the bits in a flags value, truncating the result.
779            #[inline]
780            #[must_use]
781            pub const fn complement(self) -> Self {
782                let $complement0 = self;
783                $complement
784            }
785        }
786    };
787}
788
789/// A macro that processed the input to `bitflags!` and shuffles attributes around
790/// based on whether or not they're "expression-safe".
791///
792/// This macro is a token-tree muncher that works on 2 levels:
793///
794/// For each attribute, we explicitly match on its identifier, like `cfg` to determine
795/// whether or not it should be considered expression-safe.
796///
797/// If you find yourself with an attribute that should be considered expression-safe
798/// and isn't, it can be added here.
799#[macro_export(local_inner_macros)]
800#[doc(hidden)]
801macro_rules! __bitflags_expr_safe_attrs {
802    // Entrypoint: Move all flags and all attributes into `unprocessed` lists
803    // where they'll be munched one-at-a-time
804    (
805        $(#[$inner:ident $($args:tt)*])*
806        { $e:expr }
807    ) => {
808        __bitflags_expr_safe_attrs! {
809            expr: { $e },
810            attrs: {
811                // All attributes start here
812                unprocessed: [$(#[$inner $($args)*])*],
813                // Attributes that are safe on expressions go here
814                processed: [],
815            },
816        }
817    };
818    // Process the next attribute on the current flag
819    // `cfg`: The next flag should be propagated to expressions
820    // NOTE: You can copy this rules block and replace `cfg` with
821    // your attribute name that should be considered expression-safe
822    (
823        expr: { $e:expr },
824            attrs: {
825            unprocessed: [
826                // cfg matched here
827                #[cfg $($args:tt)*]
828                $($attrs_rest:tt)*
829            ],
830            processed: [$($expr:tt)*],
831        },
832    ) => {
833        __bitflags_expr_safe_attrs! {
834            expr: { $e },
835            attrs: {
836                unprocessed: [
837                    $($attrs_rest)*
838                ],
839                processed: [
840                    $($expr)*
841                    // cfg added here
842                    #[cfg $($args)*]
843                ],
844            },
845        }
846    };
847    // Process the next attribute on the current flag
848    // `$other`: The next flag should not be propagated to expressions
849    (
850        expr: { $e:expr },
851            attrs: {
852            unprocessed: [
853                // $other matched here
854                #[$other:ident $($args:tt)*]
855                $($attrs_rest:tt)*
856            ],
857            processed: [$($expr:tt)*],
858        },
859    ) => {
860        __bitflags_expr_safe_attrs! {
861            expr: { $e },
862                attrs: {
863                unprocessed: [
864                    $($attrs_rest)*
865                ],
866                processed: [
867                    // $other not added here
868                    $($expr)*
869                ],
870            },
871        }
872    };
873    // Once all attributes on all flags are processed, generate the actual code
874    (
875        expr: { $e:expr },
876        attrs: {
877            unprocessed: [],
878            processed: [$(#[$expr:ident $($exprargs:tt)*])*],
879        },
880    ) => {
881        $(#[$expr $($exprargs)*])*
882        { $e }
883    }
884}
885
886/// Implement a flag, which may be a wildcard `_`.
887#[macro_export(local_inner_macros)]
888#[doc(hidden)]
889macro_rules! __bitflags_flag {
890    (
891        {
892            name: _,
893            named: { $($named:tt)* },
894            unnamed: { $($unnamed:tt)* },
895        }
896    ) => {
897        $($unnamed)*
898    };
899    (
900        {
901            name: $Flag:ident,
902            named: { $($named:tt)* },
903            unnamed: { $($unnamed:tt)* },
904        }
905    ) => {
906        $($named)*
907    };
908}
909
910#[macro_use]
911mod public;
912#[macro_use]
913mod internal;
914#[macro_use]
915mod external;
916
917#[cfg(feature = "example_generated")]
918pub mod example_generated;
919
920#[cfg(test)]
921mod tests;