174522d2cSopenharmony_ci// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
274522d2cSopenharmony_ci// file at the top-level directory of this distribution and at
374522d2cSopenharmony_ci// http://rust-lang.org/COPYRIGHT.
474522d2cSopenharmony_ci//
574522d2cSopenharmony_ci// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
674522d2cSopenharmony_ci// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
774522d2cSopenharmony_ci// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
874522d2cSopenharmony_ci// option. This file may not be copied, modified, or distributed
974522d2cSopenharmony_ci// except according to those terms.
1074522d2cSopenharmony_ci
1174522d2cSopenharmony_ci//! A typesafe bitmask flag generator useful for sets of C-style bitmask flags.
1274522d2cSopenharmony_ci//! It can be used for creating typesafe wrappers around C APIs.
1374522d2cSopenharmony_ci//!
1474522d2cSopenharmony_ci//! The `bitflags!` macro generates `struct`s that manage a set of flags. The
1574522d2cSopenharmony_ci//! flags should only be defined for integer types, otherwise unexpected type
1674522d2cSopenharmony_ci//! errors may occur at compile time.
1774522d2cSopenharmony_ci//!
1874522d2cSopenharmony_ci//! # Example
1974522d2cSopenharmony_ci//!
2074522d2cSopenharmony_ci//! ```
2174522d2cSopenharmony_ci//! use bitflags::bitflags;
2274522d2cSopenharmony_ci//!
2374522d2cSopenharmony_ci//! bitflags! {
2474522d2cSopenharmony_ci//!     struct Flags: u32 {
2574522d2cSopenharmony_ci//!         const A = 0b00000001;
2674522d2cSopenharmony_ci//!         const B = 0b00000010;
2774522d2cSopenharmony_ci//!         const C = 0b00000100;
2874522d2cSopenharmony_ci//!         const ABC = Self::A.bits | Self::B.bits | Self::C.bits;
2974522d2cSopenharmony_ci//!     }
3074522d2cSopenharmony_ci//! }
3174522d2cSopenharmony_ci//!
3274522d2cSopenharmony_ci//! fn main() {
3374522d2cSopenharmony_ci//!     let e1 = Flags::A | Flags::C;
3474522d2cSopenharmony_ci//!     let e2 = Flags::B | Flags::C;
3574522d2cSopenharmony_ci//!     assert_eq!((e1 | e2), Flags::ABC);   // union
3674522d2cSopenharmony_ci//!     assert_eq!((e1 & e2), Flags::C);     // intersection
3774522d2cSopenharmony_ci//!     assert_eq!((e1 - e2), Flags::A);     // set difference
3874522d2cSopenharmony_ci//!     assert_eq!(!e2, Flags::A);           // set complement
3974522d2cSopenharmony_ci//! }
4074522d2cSopenharmony_ci//! ```
4174522d2cSopenharmony_ci//!
4274522d2cSopenharmony_ci//! See [`example_generated::Flags`](./example_generated/struct.Flags.html) for documentation of code
4374522d2cSopenharmony_ci//! generated by the above `bitflags!` expansion.
4474522d2cSopenharmony_ci//!
4574522d2cSopenharmony_ci//! The generated `struct`s can also be extended with type and trait
4674522d2cSopenharmony_ci//! implementations:
4774522d2cSopenharmony_ci//!
4874522d2cSopenharmony_ci//! ```
4974522d2cSopenharmony_ci//! use std::fmt;
5074522d2cSopenharmony_ci//!
5174522d2cSopenharmony_ci//! use bitflags::bitflags;
5274522d2cSopenharmony_ci//!
5374522d2cSopenharmony_ci//! bitflags! {
5474522d2cSopenharmony_ci//!     struct Flags: u32 {
5574522d2cSopenharmony_ci//!         const A = 0b00000001;
5674522d2cSopenharmony_ci//!         const B = 0b00000010;
5774522d2cSopenharmony_ci//!     }
5874522d2cSopenharmony_ci//! }
5974522d2cSopenharmony_ci//!
6074522d2cSopenharmony_ci//! impl Flags {
6174522d2cSopenharmony_ci//!     pub fn clear(&mut self) {
6274522d2cSopenharmony_ci//!         self.bits = 0;  // The `bits` field can be accessed from within the
6374522d2cSopenharmony_ci//!                         // same module where the `bitflags!` macro was invoked.
6474522d2cSopenharmony_ci//!     }
6574522d2cSopenharmony_ci//! }
6674522d2cSopenharmony_ci//!
6774522d2cSopenharmony_ci//! impl fmt::Display for Flags {
6874522d2cSopenharmony_ci//!     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
6974522d2cSopenharmony_ci//!         write!(f, "hi!")
7074522d2cSopenharmony_ci//!     }
7174522d2cSopenharmony_ci//! }
7274522d2cSopenharmony_ci//!
7374522d2cSopenharmony_ci//! fn main() {
7474522d2cSopenharmony_ci//!     let mut flags = Flags::A | Flags::B;
7574522d2cSopenharmony_ci//!     flags.clear();
7674522d2cSopenharmony_ci//!     assert!(flags.is_empty());
7774522d2cSopenharmony_ci//!     assert_eq!(format!("{}", flags), "hi!");
7874522d2cSopenharmony_ci//!     assert_eq!(format!("{:?}", Flags::A | Flags::B), "A | B");
7974522d2cSopenharmony_ci//!     assert_eq!(format!("{:?}", Flags::B), "B");
8074522d2cSopenharmony_ci//! }
8174522d2cSopenharmony_ci//! ```
8274522d2cSopenharmony_ci//!
8374522d2cSopenharmony_ci//! # Visibility
8474522d2cSopenharmony_ci//!
8574522d2cSopenharmony_ci//! The generated structs and their associated flag constants are not exported
8674522d2cSopenharmony_ci//! out of the current module by default. A definition can be exported out of
8774522d2cSopenharmony_ci//! the current module by adding `pub` before `struct`:
8874522d2cSopenharmony_ci//!
8974522d2cSopenharmony_ci//! ```
9074522d2cSopenharmony_ci//! mod example {
9174522d2cSopenharmony_ci//!     use bitflags::bitflags;
9274522d2cSopenharmony_ci//!
9374522d2cSopenharmony_ci//!     bitflags! {
9474522d2cSopenharmony_ci//!         pub struct Flags1: u32 {
9574522d2cSopenharmony_ci//!             const A = 0b00000001;
9674522d2cSopenharmony_ci//!         }
9774522d2cSopenharmony_ci//!
9874522d2cSopenharmony_ci//! #       pub
9974522d2cSopenharmony_ci//!         struct Flags2: u32 {
10074522d2cSopenharmony_ci//!             const B = 0b00000010;
10174522d2cSopenharmony_ci//!         }
10274522d2cSopenharmony_ci//!     }
10374522d2cSopenharmony_ci//! }
10474522d2cSopenharmony_ci//!
10574522d2cSopenharmony_ci//! fn main() {
10674522d2cSopenharmony_ci//!     let flag1 = example::Flags1::A;
10774522d2cSopenharmony_ci//!     let flag2 = example::Flags2::B; // error: const `B` is private
10874522d2cSopenharmony_ci//! }
10974522d2cSopenharmony_ci//! ```
11074522d2cSopenharmony_ci//!
11174522d2cSopenharmony_ci//! # Attributes
11274522d2cSopenharmony_ci//!
11374522d2cSopenharmony_ci//! Attributes can be attached to the generated `struct`s by placing them
11474522d2cSopenharmony_ci//! before the `struct` keyword.
11574522d2cSopenharmony_ci//!
11674522d2cSopenharmony_ci//! ## Representations
11774522d2cSopenharmony_ci//!
11874522d2cSopenharmony_ci//! It's valid to add a `#[repr(C)]` or `#[repr(transparent)]` attribute to a type
11974522d2cSopenharmony_ci//! generated by `bitflags!`. In these cases, the type is guaranteed to be a newtype.
12074522d2cSopenharmony_ci//!
12174522d2cSopenharmony_ci//! ```
12274522d2cSopenharmony_ci//! use bitflags::bitflags;
12374522d2cSopenharmony_ci//!
12474522d2cSopenharmony_ci//! bitflags! {
12574522d2cSopenharmony_ci//!     #[repr(transparent)]
12674522d2cSopenharmony_ci//!     struct Flags: u32 {
12774522d2cSopenharmony_ci//!         const A = 0b00000001;
12874522d2cSopenharmony_ci//!         const B = 0b00000010;
12974522d2cSopenharmony_ci//!         const C = 0b00000100;
13074522d2cSopenharmony_ci//!     }
13174522d2cSopenharmony_ci//! }
13274522d2cSopenharmony_ci//! ```
13374522d2cSopenharmony_ci//!
13474522d2cSopenharmony_ci//! # Trait implementations
13574522d2cSopenharmony_ci//!
13674522d2cSopenharmony_ci//! The `Copy`, `Clone`, `PartialEq`, `Eq`, `PartialOrd`, `Ord` and `Hash`
13774522d2cSopenharmony_ci//! traits are automatically derived for the `struct`s using the `derive` attribute.
13874522d2cSopenharmony_ci//! Additional traits can be derived by providing an explicit `derive`
13974522d2cSopenharmony_ci//! attribute on `struct`.
14074522d2cSopenharmony_ci//!
14174522d2cSopenharmony_ci//! The `Extend` and `FromIterator` traits are implemented for the `struct`s,
14274522d2cSopenharmony_ci//! too: `Extend` adds the union of the instances of the `struct` iterated over,
14374522d2cSopenharmony_ci//! while `FromIterator` calculates the union.
14474522d2cSopenharmony_ci//!
14574522d2cSopenharmony_ci//! The `Binary`, `Debug`, `LowerHex`, `Octal` and `UpperHex` traits are also
14674522d2cSopenharmony_ci//! implemented by displaying the bits value of the internal struct.
14774522d2cSopenharmony_ci//!
14874522d2cSopenharmony_ci//! ## Operators
14974522d2cSopenharmony_ci//!
15074522d2cSopenharmony_ci//! The following operator traits are implemented for the generated `struct`s:
15174522d2cSopenharmony_ci//!
15274522d2cSopenharmony_ci//! - `BitOr` and `BitOrAssign`: union
15374522d2cSopenharmony_ci//! - `BitAnd` and `BitAndAssign`: intersection
15474522d2cSopenharmony_ci//! - `BitXor` and `BitXorAssign`: toggle
15574522d2cSopenharmony_ci//! - `Sub` and `SubAssign`: set difference
15674522d2cSopenharmony_ci//! - `Not`: set complement
15774522d2cSopenharmony_ci//!
15874522d2cSopenharmony_ci//! # Methods
15974522d2cSopenharmony_ci//!
16074522d2cSopenharmony_ci//! The following methods are defined for the generated `struct`s:
16174522d2cSopenharmony_ci//!
16274522d2cSopenharmony_ci//! - `empty`: an empty set of flags
16374522d2cSopenharmony_ci//! - `all`: the set of all defined flags
16474522d2cSopenharmony_ci//! - `bits`: the raw value of the flags currently stored
16574522d2cSopenharmony_ci//! - `from_bits`: convert from underlying bit representation, unless that
16674522d2cSopenharmony_ci//!                representation contains bits that do not correspond to a
16774522d2cSopenharmony_ci//!                defined flag
16874522d2cSopenharmony_ci//! - `from_bits_truncate`: convert from underlying bit representation, dropping
16974522d2cSopenharmony_ci//!                         any bits that do not correspond to defined flags
17074522d2cSopenharmony_ci//! - `from_bits_unchecked`: convert from underlying bit representation, keeping
17174522d2cSopenharmony_ci//!                          all bits (even those not corresponding to defined
17274522d2cSopenharmony_ci//!                          flags)
17374522d2cSopenharmony_ci//! - `is_empty`: `true` if no flags are currently stored
17474522d2cSopenharmony_ci//! - `is_all`: `true` if currently set flags exactly equal all defined flags
17574522d2cSopenharmony_ci//! - `intersects`: `true` if there are flags common to both `self` and `other`
17674522d2cSopenharmony_ci//! - `contains`: `true` if all of the flags in `other` are contained within `self`
17774522d2cSopenharmony_ci//! - `insert`: inserts the specified flags in-place
17874522d2cSopenharmony_ci//! - `remove`: removes the specified flags in-place
17974522d2cSopenharmony_ci//! - `toggle`: the specified flags will be inserted if not present, and removed
18074522d2cSopenharmony_ci//!             if they are.
18174522d2cSopenharmony_ci//! - `set`: inserts or removes the specified flags depending on the passed value
18274522d2cSopenharmony_ci//! - `intersection`: returns a new set of flags, containing only the flags present
18374522d2cSopenharmony_ci//!                   in both `self` and `other` (the argument to the function).
18474522d2cSopenharmony_ci//! - `union`: returns a new set of flags, containing any flags present in
18574522d2cSopenharmony_ci//!            either `self` or `other` (the argument to the function).
18674522d2cSopenharmony_ci//! - `difference`: returns a new set of flags, containing all flags present in
18774522d2cSopenharmony_ci//!                 `self` without any of the flags present in `other` (the
18874522d2cSopenharmony_ci//!                 argument to the function).
18974522d2cSopenharmony_ci//! - `symmetric_difference`: returns a new set of flags, containing all flags
19074522d2cSopenharmony_ci//!                           present in either `self` or `other` (the argument
19174522d2cSopenharmony_ci//!                           to the function), but not both.
19274522d2cSopenharmony_ci//! - `complement`: returns a new set of flags, containing all flags which are
19374522d2cSopenharmony_ci//!                 not set in `self`, but which are allowed for this type.
19474522d2cSopenharmony_ci//!
19574522d2cSopenharmony_ci//! ## Default
19674522d2cSopenharmony_ci//!
19774522d2cSopenharmony_ci//! The `Default` trait is not automatically implemented for the generated structs.
19874522d2cSopenharmony_ci//!
19974522d2cSopenharmony_ci//! If your default value is equal to `0` (which is the same value as calling `empty()`
20074522d2cSopenharmony_ci//! on the generated struct), you can simply derive `Default`:
20174522d2cSopenharmony_ci//!
20274522d2cSopenharmony_ci//! ```
20374522d2cSopenharmony_ci//! use bitflags::bitflags;
20474522d2cSopenharmony_ci//!
20574522d2cSopenharmony_ci//! bitflags! {
20674522d2cSopenharmony_ci//!     // Results in default value with bits: 0
20774522d2cSopenharmony_ci//!     #[derive(Default)]
20874522d2cSopenharmony_ci//!     struct Flags: u32 {
20974522d2cSopenharmony_ci//!         const A = 0b00000001;
21074522d2cSopenharmony_ci//!         const B = 0b00000010;
21174522d2cSopenharmony_ci//!         const C = 0b00000100;
21274522d2cSopenharmony_ci//!     }
21374522d2cSopenharmony_ci//! }
21474522d2cSopenharmony_ci//!
21574522d2cSopenharmony_ci//! fn main() {
21674522d2cSopenharmony_ci//!     let derived_default: Flags = Default::default();
21774522d2cSopenharmony_ci//!     assert_eq!(derived_default.bits(), 0);
21874522d2cSopenharmony_ci//! }
21974522d2cSopenharmony_ci//! ```
22074522d2cSopenharmony_ci//!
22174522d2cSopenharmony_ci//! If your default value is not equal to `0` you need to implement `Default` yourself:
22274522d2cSopenharmony_ci//!
22374522d2cSopenharmony_ci//! ```
22474522d2cSopenharmony_ci//! use bitflags::bitflags;
22574522d2cSopenharmony_ci//!
22674522d2cSopenharmony_ci//! bitflags! {
22774522d2cSopenharmony_ci//!     struct Flags: u32 {
22874522d2cSopenharmony_ci//!         const A = 0b00000001;
22974522d2cSopenharmony_ci//!         const B = 0b00000010;
23074522d2cSopenharmony_ci//!         const C = 0b00000100;
23174522d2cSopenharmony_ci//!     }
23274522d2cSopenharmony_ci//! }
23374522d2cSopenharmony_ci//!
23474522d2cSopenharmony_ci//! // explicit `Default` implementation
23574522d2cSopenharmony_ci//! impl Default for Flags {
23674522d2cSopenharmony_ci//!     fn default() -> Flags {
23774522d2cSopenharmony_ci//!         Flags::A | Flags::C
23874522d2cSopenharmony_ci//!     }
23974522d2cSopenharmony_ci//! }
24074522d2cSopenharmony_ci//!
24174522d2cSopenharmony_ci//! fn main() {
24274522d2cSopenharmony_ci//!     let implemented_default: Flags = Default::default();
24374522d2cSopenharmony_ci//!     assert_eq!(implemented_default, (Flags::A | Flags::C));
24474522d2cSopenharmony_ci//! }
24574522d2cSopenharmony_ci//! ```
24674522d2cSopenharmony_ci//!
24774522d2cSopenharmony_ci//! # Zero Flags
24874522d2cSopenharmony_ci//!
24974522d2cSopenharmony_ci//! Flags with a value equal to zero will have some strange behavior that one should be aware of.
25074522d2cSopenharmony_ci//!
25174522d2cSopenharmony_ci//! ```
25274522d2cSopenharmony_ci//! use bitflags::bitflags;
25374522d2cSopenharmony_ci//!
25474522d2cSopenharmony_ci//! bitflags! {
25574522d2cSopenharmony_ci//!     struct Flags: u32 {
25674522d2cSopenharmony_ci//!         const NONE = 0b00000000;
25774522d2cSopenharmony_ci//!         const SOME = 0b00000001;
25874522d2cSopenharmony_ci//!     }
25974522d2cSopenharmony_ci//! }
26074522d2cSopenharmony_ci//!
26174522d2cSopenharmony_ci//! fn main() {
26274522d2cSopenharmony_ci//!     let empty = Flags::empty();
26374522d2cSopenharmony_ci//!     let none = Flags::NONE;
26474522d2cSopenharmony_ci//!     let some = Flags::SOME;
26574522d2cSopenharmony_ci//!
26674522d2cSopenharmony_ci//!     // Zero flags are treated as always present
26774522d2cSopenharmony_ci//!     assert!(empty.contains(Flags::NONE));
26874522d2cSopenharmony_ci//!     assert!(none.contains(Flags::NONE));
26974522d2cSopenharmony_ci//!     assert!(some.contains(Flags::NONE));
27074522d2cSopenharmony_ci//!
27174522d2cSopenharmony_ci//!     // Zero flags will be ignored when testing for emptiness
27274522d2cSopenharmony_ci//!     assert!(none.is_empty());
27374522d2cSopenharmony_ci//! }
27474522d2cSopenharmony_ci//! ```
27574522d2cSopenharmony_ci//!
27674522d2cSopenharmony_ci//! Users should generally avoid defining a flag with a value of zero.
27774522d2cSopenharmony_ci
27874522d2cSopenharmony_ci#![cfg_attr(not(test), no_std)]
27974522d2cSopenharmony_ci#![doc(html_root_url = "https://docs.rs/bitflags/1.3.2")]
28074522d2cSopenharmony_ci
28174522d2cSopenharmony_ci#[doc(hidden)]
28274522d2cSopenharmony_cipub extern crate core as _core;
28374522d2cSopenharmony_ci
28474522d2cSopenharmony_ci/// The macro used to generate the flag structures.
28574522d2cSopenharmony_ci///
28674522d2cSopenharmony_ci/// See the [crate level docs](../bitflags/index.html) for complete documentation.
28774522d2cSopenharmony_ci///
28874522d2cSopenharmony_ci/// # Example
28974522d2cSopenharmony_ci///
29074522d2cSopenharmony_ci/// ```
29174522d2cSopenharmony_ci/// use bitflags::bitflags;
29274522d2cSopenharmony_ci///
29374522d2cSopenharmony_ci/// bitflags! {
29474522d2cSopenharmony_ci///     struct Flags: u32 {
29574522d2cSopenharmony_ci///         const A = 0b00000001;
29674522d2cSopenharmony_ci///         const B = 0b00000010;
29774522d2cSopenharmony_ci///         const C = 0b00000100;
29874522d2cSopenharmony_ci///         const ABC = Self::A.bits | Self::B.bits | Self::C.bits;
29974522d2cSopenharmony_ci///     }
30074522d2cSopenharmony_ci/// }
30174522d2cSopenharmony_ci///
30274522d2cSopenharmony_ci/// fn main() {
30374522d2cSopenharmony_ci///     let e1 = Flags::A | Flags::C;
30474522d2cSopenharmony_ci///     let e2 = Flags::B | Flags::C;
30574522d2cSopenharmony_ci///     assert_eq!((e1 | e2), Flags::ABC);   // union
30674522d2cSopenharmony_ci///     assert_eq!((e1 & e2), Flags::C);     // intersection
30774522d2cSopenharmony_ci///     assert_eq!((e1 - e2), Flags::A);     // set difference
30874522d2cSopenharmony_ci///     assert_eq!(!e2, Flags::A);           // set complement
30974522d2cSopenharmony_ci/// }
31074522d2cSopenharmony_ci/// ```
31174522d2cSopenharmony_ci///
31274522d2cSopenharmony_ci/// The generated `struct`s can also be extended with type and trait
31374522d2cSopenharmony_ci/// implementations:
31474522d2cSopenharmony_ci///
31574522d2cSopenharmony_ci/// ```
31674522d2cSopenharmony_ci/// use std::fmt;
31774522d2cSopenharmony_ci///
31874522d2cSopenharmony_ci/// use bitflags::bitflags;
31974522d2cSopenharmony_ci///
32074522d2cSopenharmony_ci/// bitflags! {
32174522d2cSopenharmony_ci///     struct Flags: u32 {
32274522d2cSopenharmony_ci///         const A = 0b00000001;
32374522d2cSopenharmony_ci///         const B = 0b00000010;
32474522d2cSopenharmony_ci///     }
32574522d2cSopenharmony_ci/// }
32674522d2cSopenharmony_ci///
32774522d2cSopenharmony_ci/// impl Flags {
32874522d2cSopenharmony_ci///     pub fn clear(&mut self) {
32974522d2cSopenharmony_ci///         self.bits = 0;  // The `bits` field can be accessed from within the
33074522d2cSopenharmony_ci///                         // same module where the `bitflags!` macro was invoked.
33174522d2cSopenharmony_ci///     }
33274522d2cSopenharmony_ci/// }
33374522d2cSopenharmony_ci///
33474522d2cSopenharmony_ci/// impl fmt::Display for Flags {
33574522d2cSopenharmony_ci///     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
33674522d2cSopenharmony_ci///         write!(f, "hi!")
33774522d2cSopenharmony_ci///     }
33874522d2cSopenharmony_ci/// }
33974522d2cSopenharmony_ci///
34074522d2cSopenharmony_ci/// fn main() {
34174522d2cSopenharmony_ci///     let mut flags = Flags::A | Flags::B;
34274522d2cSopenharmony_ci///     flags.clear();
34374522d2cSopenharmony_ci///     assert!(flags.is_empty());
34474522d2cSopenharmony_ci///     assert_eq!(format!("{}", flags), "hi!");
34574522d2cSopenharmony_ci///     assert_eq!(format!("{:?}", Flags::A | Flags::B), "A | B");
34674522d2cSopenharmony_ci///     assert_eq!(format!("{:?}", Flags::B), "B");
34774522d2cSopenharmony_ci/// }
34874522d2cSopenharmony_ci/// ```
34974522d2cSopenharmony_ci#[macro_export(local_inner_macros)]
35074522d2cSopenharmony_cimacro_rules! bitflags {
35174522d2cSopenharmony_ci    (
35274522d2cSopenharmony_ci        $(#[$outer:meta])*
35374522d2cSopenharmony_ci        $vis:vis struct $BitFlags:ident: $T:ty {
35474522d2cSopenharmony_ci            $(
35574522d2cSopenharmony_ci                $(#[$inner:ident $($args:tt)*])*
35674522d2cSopenharmony_ci                const $Flag:ident = $value:expr;
35774522d2cSopenharmony_ci            )*
35874522d2cSopenharmony_ci        }
35974522d2cSopenharmony_ci
36074522d2cSopenharmony_ci        $($t:tt)*
36174522d2cSopenharmony_ci    ) => {
36274522d2cSopenharmony_ci        $(#[$outer])*
36374522d2cSopenharmony_ci        #[derive(Copy, PartialEq, Eq, Clone, PartialOrd, Ord, Hash)]
36474522d2cSopenharmony_ci        $vis struct $BitFlags {
36574522d2cSopenharmony_ci            bits: $T,
36674522d2cSopenharmony_ci        }
36774522d2cSopenharmony_ci
36874522d2cSopenharmony_ci        __impl_bitflags! {
36974522d2cSopenharmony_ci            $BitFlags: $T {
37074522d2cSopenharmony_ci                $(
37174522d2cSopenharmony_ci                    $(#[$inner $($args)*])*
37274522d2cSopenharmony_ci                    $Flag = $value;
37374522d2cSopenharmony_ci                )*
37474522d2cSopenharmony_ci            }
37574522d2cSopenharmony_ci        }
37674522d2cSopenharmony_ci
37774522d2cSopenharmony_ci        bitflags! {
37874522d2cSopenharmony_ci            $($t)*
37974522d2cSopenharmony_ci        }
38074522d2cSopenharmony_ci    };
38174522d2cSopenharmony_ci    () => {};
38274522d2cSopenharmony_ci}
38374522d2cSopenharmony_ci
38474522d2cSopenharmony_ci// A helper macro to implement the `all` function.
38574522d2cSopenharmony_ci#[macro_export(local_inner_macros)]
38674522d2cSopenharmony_ci#[doc(hidden)]
38774522d2cSopenharmony_cimacro_rules! __impl_all_bitflags {
38874522d2cSopenharmony_ci    (
38974522d2cSopenharmony_ci        $BitFlags:ident: $T:ty {
39074522d2cSopenharmony_ci            $(
39174522d2cSopenharmony_ci                $(#[$attr:ident $($args:tt)*])*
39274522d2cSopenharmony_ci                $Flag:ident = $value:expr;
39374522d2cSopenharmony_ci            )+
39474522d2cSopenharmony_ci        }
39574522d2cSopenharmony_ci    ) => {
39674522d2cSopenharmony_ci        // See `Debug::fmt` for why this approach is taken.
39774522d2cSopenharmony_ci        #[allow(non_snake_case)]
39874522d2cSopenharmony_ci        trait __BitFlags {
39974522d2cSopenharmony_ci            $(
40074522d2cSopenharmony_ci                const $Flag: $T = 0;
40174522d2cSopenharmony_ci            )+
40274522d2cSopenharmony_ci        }
40374522d2cSopenharmony_ci        #[allow(non_snake_case)]
40474522d2cSopenharmony_ci        impl __BitFlags for $BitFlags {
40574522d2cSopenharmony_ci            $(
40674522d2cSopenharmony_ci                __impl_bitflags! {
40774522d2cSopenharmony_ci                    #[allow(deprecated)]
40874522d2cSopenharmony_ci                    $(? #[$attr $($args)*])*
40974522d2cSopenharmony_ci                    const $Flag: $T = Self::$Flag.bits;
41074522d2cSopenharmony_ci                }
41174522d2cSopenharmony_ci            )+
41274522d2cSopenharmony_ci        }
41374522d2cSopenharmony_ci        Self { bits: $(<Self as __BitFlags>::$Flag)|+ }
41474522d2cSopenharmony_ci    };
41574522d2cSopenharmony_ci    (
41674522d2cSopenharmony_ci        $BitFlags:ident: $T:ty { }
41774522d2cSopenharmony_ci    ) => {
41874522d2cSopenharmony_ci        Self { bits: 0 }
41974522d2cSopenharmony_ci    };
42074522d2cSopenharmony_ci}
42174522d2cSopenharmony_ci
42274522d2cSopenharmony_ci#[macro_export(local_inner_macros)]
42374522d2cSopenharmony_ci#[doc(hidden)]
42474522d2cSopenharmony_cimacro_rules! __impl_bitflags {
42574522d2cSopenharmony_ci    (
42674522d2cSopenharmony_ci        $BitFlags:ident: $T:ty {
42774522d2cSopenharmony_ci            $(
42874522d2cSopenharmony_ci                $(#[$attr:ident $($args:tt)*])*
42974522d2cSopenharmony_ci                $Flag:ident = $value:expr;
43074522d2cSopenharmony_ci            )*
43174522d2cSopenharmony_ci        }
43274522d2cSopenharmony_ci    ) => {
43374522d2cSopenharmony_ci        impl $crate::_core::fmt::Debug for $BitFlags {
43474522d2cSopenharmony_ci            fn fmt(&self, f: &mut $crate::_core::fmt::Formatter) -> $crate::_core::fmt::Result {
43574522d2cSopenharmony_ci                // This convoluted approach is to handle #[cfg]-based flag
43674522d2cSopenharmony_ci                // omission correctly. For example it needs to support:
43774522d2cSopenharmony_ci                //
43874522d2cSopenharmony_ci                //    #[cfg(unix)] const A: Flag = /* ... */;
43974522d2cSopenharmony_ci                //    #[cfg(windows)] const B: Flag = /* ... */;
44074522d2cSopenharmony_ci
44174522d2cSopenharmony_ci                // Unconditionally define a check for every flag, even disabled
44274522d2cSopenharmony_ci                // ones.
44374522d2cSopenharmony_ci                #[allow(non_snake_case)]
44474522d2cSopenharmony_ci                trait __BitFlags {
44574522d2cSopenharmony_ci                    $(
44674522d2cSopenharmony_ci                        #[inline]
44774522d2cSopenharmony_ci                        fn $Flag(&self) -> bool { false }
44874522d2cSopenharmony_ci                    )*
44974522d2cSopenharmony_ci                }
45074522d2cSopenharmony_ci
45174522d2cSopenharmony_ci                // Conditionally override the check for just those flags that
45274522d2cSopenharmony_ci                // are not #[cfg]ed away.
45374522d2cSopenharmony_ci                #[allow(non_snake_case)]
45474522d2cSopenharmony_ci                impl __BitFlags for $BitFlags {
45574522d2cSopenharmony_ci                    $(
45674522d2cSopenharmony_ci                        __impl_bitflags! {
45774522d2cSopenharmony_ci                            #[allow(deprecated)]
45874522d2cSopenharmony_ci                            #[inline]
45974522d2cSopenharmony_ci                            $(? #[$attr $($args)*])*
46074522d2cSopenharmony_ci                            fn $Flag(&self) -> bool {
46174522d2cSopenharmony_ci                                if Self::$Flag.bits == 0 && self.bits != 0 {
46274522d2cSopenharmony_ci                                    false
46374522d2cSopenharmony_ci                                } else {
46474522d2cSopenharmony_ci                                    self.bits & Self::$Flag.bits == Self::$Flag.bits
46574522d2cSopenharmony_ci                                }
46674522d2cSopenharmony_ci                            }
46774522d2cSopenharmony_ci                        }
46874522d2cSopenharmony_ci                    )*
46974522d2cSopenharmony_ci                }
47074522d2cSopenharmony_ci
47174522d2cSopenharmony_ci                let mut first = true;
47274522d2cSopenharmony_ci                $(
47374522d2cSopenharmony_ci                    if <Self as __BitFlags>::$Flag(self) {
47474522d2cSopenharmony_ci                        if !first {
47574522d2cSopenharmony_ci                            f.write_str(" | ")?;
47674522d2cSopenharmony_ci                        }
47774522d2cSopenharmony_ci                        first = false;
47874522d2cSopenharmony_ci                        f.write_str($crate::_core::stringify!($Flag))?;
47974522d2cSopenharmony_ci                    }
48074522d2cSopenharmony_ci                )*
48174522d2cSopenharmony_ci                let extra_bits = self.bits & !Self::all().bits();
48274522d2cSopenharmony_ci                if extra_bits != 0 {
48374522d2cSopenharmony_ci                    if !first {
48474522d2cSopenharmony_ci                        f.write_str(" | ")?;
48574522d2cSopenharmony_ci                    }
48674522d2cSopenharmony_ci                    first = false;
48774522d2cSopenharmony_ci                    f.write_str("0x")?;
48874522d2cSopenharmony_ci                    $crate::_core::fmt::LowerHex::fmt(&extra_bits, f)?;
48974522d2cSopenharmony_ci                }
49074522d2cSopenharmony_ci                if first {
49174522d2cSopenharmony_ci                    f.write_str("(empty)")?;
49274522d2cSopenharmony_ci                }
49374522d2cSopenharmony_ci                Ok(())
49474522d2cSopenharmony_ci            }
49574522d2cSopenharmony_ci        }
49674522d2cSopenharmony_ci        impl $crate::_core::fmt::Binary for $BitFlags {
49774522d2cSopenharmony_ci            fn fmt(&self, f: &mut $crate::_core::fmt::Formatter) -> $crate::_core::fmt::Result {
49874522d2cSopenharmony_ci                $crate::_core::fmt::Binary::fmt(&self.bits, f)
49974522d2cSopenharmony_ci            }
50074522d2cSopenharmony_ci        }
50174522d2cSopenharmony_ci        impl $crate::_core::fmt::Octal for $BitFlags {
50274522d2cSopenharmony_ci            fn fmt(&self, f: &mut $crate::_core::fmt::Formatter) -> $crate::_core::fmt::Result {
50374522d2cSopenharmony_ci                $crate::_core::fmt::Octal::fmt(&self.bits, f)
50474522d2cSopenharmony_ci            }
50574522d2cSopenharmony_ci        }
50674522d2cSopenharmony_ci        impl $crate::_core::fmt::LowerHex for $BitFlags {
50774522d2cSopenharmony_ci            fn fmt(&self, f: &mut $crate::_core::fmt::Formatter) -> $crate::_core::fmt::Result {
50874522d2cSopenharmony_ci                $crate::_core::fmt::LowerHex::fmt(&self.bits, f)
50974522d2cSopenharmony_ci            }
51074522d2cSopenharmony_ci        }
51174522d2cSopenharmony_ci        impl $crate::_core::fmt::UpperHex for $BitFlags {
51274522d2cSopenharmony_ci            fn fmt(&self, f: &mut $crate::_core::fmt::Formatter) -> $crate::_core::fmt::Result {
51374522d2cSopenharmony_ci                $crate::_core::fmt::UpperHex::fmt(&self.bits, f)
51474522d2cSopenharmony_ci            }
51574522d2cSopenharmony_ci        }
51674522d2cSopenharmony_ci
51774522d2cSopenharmony_ci        #[allow(dead_code)]
51874522d2cSopenharmony_ci        impl $BitFlags {
51974522d2cSopenharmony_ci            $(
52074522d2cSopenharmony_ci                $(#[$attr $($args)*])*
52174522d2cSopenharmony_ci                pub const $Flag: Self = Self { bits: $value };
52274522d2cSopenharmony_ci            )*
52374522d2cSopenharmony_ci
52474522d2cSopenharmony_ci            /// Returns an empty set of flags.
52574522d2cSopenharmony_ci            #[inline]
52674522d2cSopenharmony_ci            pub const fn empty() -> Self {
52774522d2cSopenharmony_ci                Self { bits: 0 }
52874522d2cSopenharmony_ci            }
52974522d2cSopenharmony_ci
53074522d2cSopenharmony_ci            /// Returns the set containing all flags.
53174522d2cSopenharmony_ci            #[inline]
53274522d2cSopenharmony_ci            pub const fn all() -> Self {
53374522d2cSopenharmony_ci                __impl_all_bitflags! {
53474522d2cSopenharmony_ci                    $BitFlags: $T {
53574522d2cSopenharmony_ci                        $(
53674522d2cSopenharmony_ci                            $(#[$attr $($args)*])*
53774522d2cSopenharmony_ci                            $Flag = $value;
53874522d2cSopenharmony_ci                        )*
53974522d2cSopenharmony_ci                    }
54074522d2cSopenharmony_ci                }
54174522d2cSopenharmony_ci            }
54274522d2cSopenharmony_ci
54374522d2cSopenharmony_ci            /// Returns the raw value of the flags currently stored.
54474522d2cSopenharmony_ci            #[inline]
54574522d2cSopenharmony_ci            pub const fn bits(&self) -> $T {
54674522d2cSopenharmony_ci                self.bits
54774522d2cSopenharmony_ci            }
54874522d2cSopenharmony_ci
54974522d2cSopenharmony_ci            /// Convert from underlying bit representation, unless that
55074522d2cSopenharmony_ci            /// representation contains bits that do not correspond to a flag.
55174522d2cSopenharmony_ci            #[inline]
55274522d2cSopenharmony_ci            pub const fn from_bits(bits: $T) -> $crate::_core::option::Option<Self> {
55374522d2cSopenharmony_ci                if (bits & !Self::all().bits()) == 0 {
55474522d2cSopenharmony_ci                    $crate::_core::option::Option::Some(Self { bits })
55574522d2cSopenharmony_ci                } else {
55674522d2cSopenharmony_ci                    $crate::_core::option::Option::None
55774522d2cSopenharmony_ci                }
55874522d2cSopenharmony_ci            }
55974522d2cSopenharmony_ci
56074522d2cSopenharmony_ci            /// Convert from underlying bit representation, dropping any bits
56174522d2cSopenharmony_ci            /// that do not correspond to flags.
56274522d2cSopenharmony_ci            #[inline]
56374522d2cSopenharmony_ci            pub const fn from_bits_truncate(bits: $T) -> Self {
56474522d2cSopenharmony_ci                Self { bits: bits & Self::all().bits }
56574522d2cSopenharmony_ci            }
56674522d2cSopenharmony_ci
56774522d2cSopenharmony_ci            /// Convert from underlying bit representation, preserving all
56874522d2cSopenharmony_ci            /// bits (even those not corresponding to a defined flag).
56974522d2cSopenharmony_ci            ///
57074522d2cSopenharmony_ci            /// # Safety
57174522d2cSopenharmony_ci            ///
57274522d2cSopenharmony_ci            /// The caller of the `bitflags!` macro can chose to allow or
57374522d2cSopenharmony_ci            /// disallow extra bits for their bitflags type.
57474522d2cSopenharmony_ci            ///
57574522d2cSopenharmony_ci            /// The caller of `from_bits_unchecked()` has to ensure that
57674522d2cSopenharmony_ci            /// all bits correspond to a defined flag or that extra bits
57774522d2cSopenharmony_ci            /// are valid for this bitflags type.
57874522d2cSopenharmony_ci            #[inline]
57974522d2cSopenharmony_ci            pub const unsafe fn from_bits_unchecked(bits: $T) -> Self {
58074522d2cSopenharmony_ci                Self { bits }
58174522d2cSopenharmony_ci            }
58274522d2cSopenharmony_ci
58374522d2cSopenharmony_ci            /// Returns `true` if no flags are currently stored.
58474522d2cSopenharmony_ci            #[inline]
58574522d2cSopenharmony_ci            pub const fn is_empty(&self) -> bool {
58674522d2cSopenharmony_ci                self.bits() == Self::empty().bits()
58774522d2cSopenharmony_ci            }
58874522d2cSopenharmony_ci
58974522d2cSopenharmony_ci            /// Returns `true` if all flags are currently set.
59074522d2cSopenharmony_ci            #[inline]
59174522d2cSopenharmony_ci            pub const fn is_all(&self) -> bool {
59274522d2cSopenharmony_ci                Self::all().bits | self.bits == self.bits
59374522d2cSopenharmony_ci            }
59474522d2cSopenharmony_ci
59574522d2cSopenharmony_ci            /// Returns `true` if there are flags common to both `self` and `other`.
59674522d2cSopenharmony_ci            #[inline]
59774522d2cSopenharmony_ci            pub const fn intersects(&self, other: Self) -> bool {
59874522d2cSopenharmony_ci                !(Self { bits: self.bits & other.bits}).is_empty()
59974522d2cSopenharmony_ci            }
60074522d2cSopenharmony_ci
60174522d2cSopenharmony_ci            /// Returns `true` if all of the flags in `other` are contained within `self`.
60274522d2cSopenharmony_ci            #[inline]
60374522d2cSopenharmony_ci            pub const fn contains(&self, other: Self) -> bool {
60474522d2cSopenharmony_ci                (self.bits & other.bits) == other.bits
60574522d2cSopenharmony_ci            }
60674522d2cSopenharmony_ci
60774522d2cSopenharmony_ci            /// Inserts the specified flags in-place.
60874522d2cSopenharmony_ci            #[inline]
60974522d2cSopenharmony_ci            pub fn insert(&mut self, other: Self) {
61074522d2cSopenharmony_ci                self.bits |= other.bits;
61174522d2cSopenharmony_ci            }
61274522d2cSopenharmony_ci
61374522d2cSopenharmony_ci            /// Removes the specified flags in-place.
61474522d2cSopenharmony_ci            #[inline]
61574522d2cSopenharmony_ci            pub fn remove(&mut self, other: Self) {
61674522d2cSopenharmony_ci                self.bits &= !other.bits;
61774522d2cSopenharmony_ci            }
61874522d2cSopenharmony_ci
61974522d2cSopenharmony_ci            /// Toggles the specified flags in-place.
62074522d2cSopenharmony_ci            #[inline]
62174522d2cSopenharmony_ci            pub fn toggle(&mut self, other: Self) {
62274522d2cSopenharmony_ci                self.bits ^= other.bits;
62374522d2cSopenharmony_ci            }
62474522d2cSopenharmony_ci
62574522d2cSopenharmony_ci            /// Inserts or removes the specified flags depending on the passed value.
62674522d2cSopenharmony_ci            #[inline]
62774522d2cSopenharmony_ci            pub fn set(&mut self, other: Self, value: bool) {
62874522d2cSopenharmony_ci                if value {
62974522d2cSopenharmony_ci                    self.insert(other);
63074522d2cSopenharmony_ci                } else {
63174522d2cSopenharmony_ci                    self.remove(other);
63274522d2cSopenharmony_ci                }
63374522d2cSopenharmony_ci            }
63474522d2cSopenharmony_ci
63574522d2cSopenharmony_ci            /// Returns the intersection between the flags in `self` and
63674522d2cSopenharmony_ci            /// `other`.
63774522d2cSopenharmony_ci            ///
63874522d2cSopenharmony_ci            /// Specifically, the returned set contains only the flags which are
63974522d2cSopenharmony_ci            /// present in *both* `self` *and* `other`.
64074522d2cSopenharmony_ci            ///
64174522d2cSopenharmony_ci            /// This is equivalent to using the `&` operator (e.g.
64274522d2cSopenharmony_ci            /// [`ops::BitAnd`]), as in `flags & other`.
64374522d2cSopenharmony_ci            ///
64474522d2cSopenharmony_ci            /// [`ops::BitAnd`]: https://doc.rust-lang.org/std/ops/trait.BitAnd.html
64574522d2cSopenharmony_ci            #[inline]
64674522d2cSopenharmony_ci            #[must_use]
64774522d2cSopenharmony_ci            pub const fn intersection(self, other: Self) -> Self {
64874522d2cSopenharmony_ci                Self { bits: self.bits & other.bits }
64974522d2cSopenharmony_ci            }
65074522d2cSopenharmony_ci
65174522d2cSopenharmony_ci            /// Returns the union of between the flags in `self` and `other`.
65274522d2cSopenharmony_ci            ///
65374522d2cSopenharmony_ci            /// Specifically, the returned set contains all flags which are
65474522d2cSopenharmony_ci            /// present in *either* `self` *or* `other`, including any which are
65574522d2cSopenharmony_ci            /// present in both (see [`Self::symmetric_difference`] if that
65674522d2cSopenharmony_ci            /// is undesirable).
65774522d2cSopenharmony_ci            ///
65874522d2cSopenharmony_ci            /// This is equivalent to using the `|` operator (e.g.
65974522d2cSopenharmony_ci            /// [`ops::BitOr`]), as in `flags | other`.
66074522d2cSopenharmony_ci            ///
66174522d2cSopenharmony_ci            /// [`ops::BitOr`]: https://doc.rust-lang.org/std/ops/trait.BitOr.html
66274522d2cSopenharmony_ci            #[inline]
66374522d2cSopenharmony_ci            #[must_use]
66474522d2cSopenharmony_ci            pub const fn union(self, other: Self) -> Self {
66574522d2cSopenharmony_ci                Self { bits: self.bits | other.bits }
66674522d2cSopenharmony_ci            }
66774522d2cSopenharmony_ci
66874522d2cSopenharmony_ci            /// Returns the difference between the flags in `self` and `other`.
66974522d2cSopenharmony_ci            ///
67074522d2cSopenharmony_ci            /// Specifically, the returned set contains all flags present in
67174522d2cSopenharmony_ci            /// `self`, except for the ones present in `other`.
67274522d2cSopenharmony_ci            ///
67374522d2cSopenharmony_ci            /// It is also conceptually equivalent to the "bit-clear" operation:
67474522d2cSopenharmony_ci            /// `flags & !other` (and this syntax is also supported).
67574522d2cSopenharmony_ci            ///
67674522d2cSopenharmony_ci            /// This is equivalent to using the `-` operator (e.g.
67774522d2cSopenharmony_ci            /// [`ops::Sub`]), as in `flags - other`.
67874522d2cSopenharmony_ci            ///
67974522d2cSopenharmony_ci            /// [`ops::Sub`]: https://doc.rust-lang.org/std/ops/trait.Sub.html
68074522d2cSopenharmony_ci            #[inline]
68174522d2cSopenharmony_ci            #[must_use]
68274522d2cSopenharmony_ci            pub const fn difference(self, other: Self) -> Self {
68374522d2cSopenharmony_ci                Self { bits: self.bits & !other.bits }
68474522d2cSopenharmony_ci            }
68574522d2cSopenharmony_ci
68674522d2cSopenharmony_ci            /// Returns the [symmetric difference][sym-diff] between the flags
68774522d2cSopenharmony_ci            /// in `self` and `other`.
68874522d2cSopenharmony_ci            ///
68974522d2cSopenharmony_ci            /// Specifically, the returned set contains the flags present which
69074522d2cSopenharmony_ci            /// are present in `self` or `other`, but that are not present in
69174522d2cSopenharmony_ci            /// both. Equivalently, it contains the flags present in *exactly
69274522d2cSopenharmony_ci            /// one* of the sets `self` and `other`.
69374522d2cSopenharmony_ci            ///
69474522d2cSopenharmony_ci            /// This is equivalent to using the `^` operator (e.g.
69574522d2cSopenharmony_ci            /// [`ops::BitXor`]), as in `flags ^ other`.
69674522d2cSopenharmony_ci            ///
69774522d2cSopenharmony_ci            /// [sym-diff]: https://en.wikipedia.org/wiki/Symmetric_difference
69874522d2cSopenharmony_ci            /// [`ops::BitXor`]: https://doc.rust-lang.org/std/ops/trait.BitXor.html
69974522d2cSopenharmony_ci            #[inline]
70074522d2cSopenharmony_ci            #[must_use]
70174522d2cSopenharmony_ci            pub const fn symmetric_difference(self, other: Self) -> Self {
70274522d2cSopenharmony_ci                Self { bits: self.bits ^ other.bits }
70374522d2cSopenharmony_ci            }
70474522d2cSopenharmony_ci
70574522d2cSopenharmony_ci            /// Returns the complement of this set of flags.
70674522d2cSopenharmony_ci            ///
70774522d2cSopenharmony_ci            /// Specifically, the returned set contains all the flags which are
70874522d2cSopenharmony_ci            /// not set in `self`, but which are allowed for this type.
70974522d2cSopenharmony_ci            ///
71074522d2cSopenharmony_ci            /// Alternatively, it can be thought of as the set difference
71174522d2cSopenharmony_ci            /// between [`Self::all()`] and `self` (e.g. `Self::all() - self`)
71274522d2cSopenharmony_ci            ///
71374522d2cSopenharmony_ci            /// This is equivalent to using the `!` operator (e.g.
71474522d2cSopenharmony_ci            /// [`ops::Not`]), as in `!flags`.
71574522d2cSopenharmony_ci            ///
71674522d2cSopenharmony_ci            /// [`Self::all()`]: Self::all
71774522d2cSopenharmony_ci            /// [`ops::Not`]: https://doc.rust-lang.org/std/ops/trait.Not.html
71874522d2cSopenharmony_ci            #[inline]
71974522d2cSopenharmony_ci            #[must_use]
72074522d2cSopenharmony_ci            pub const fn complement(self) -> Self {
72174522d2cSopenharmony_ci                Self::from_bits_truncate(!self.bits)
72274522d2cSopenharmony_ci            }
72374522d2cSopenharmony_ci
72474522d2cSopenharmony_ci        }
72574522d2cSopenharmony_ci
72674522d2cSopenharmony_ci        impl $crate::_core::ops::BitOr for $BitFlags {
72774522d2cSopenharmony_ci            type Output = Self;
72874522d2cSopenharmony_ci
72974522d2cSopenharmony_ci            /// Returns the union of the two sets of flags.
73074522d2cSopenharmony_ci            #[inline]
73174522d2cSopenharmony_ci            fn bitor(self, other: $BitFlags) -> Self {
73274522d2cSopenharmony_ci                Self { bits: self.bits | other.bits }
73374522d2cSopenharmony_ci            }
73474522d2cSopenharmony_ci        }
73574522d2cSopenharmony_ci
73674522d2cSopenharmony_ci        impl $crate::_core::ops::BitOrAssign for $BitFlags {
73774522d2cSopenharmony_ci            /// Adds the set of flags.
73874522d2cSopenharmony_ci            #[inline]
73974522d2cSopenharmony_ci            fn bitor_assign(&mut self, other: Self) {
74074522d2cSopenharmony_ci                self.bits |= other.bits;
74174522d2cSopenharmony_ci            }
74274522d2cSopenharmony_ci        }
74374522d2cSopenharmony_ci
74474522d2cSopenharmony_ci        impl $crate::_core::ops::BitXor for $BitFlags {
74574522d2cSopenharmony_ci            type Output = Self;
74674522d2cSopenharmony_ci
74774522d2cSopenharmony_ci            /// Returns the left flags, but with all the right flags toggled.
74874522d2cSopenharmony_ci            #[inline]
74974522d2cSopenharmony_ci            fn bitxor(self, other: Self) -> Self {
75074522d2cSopenharmony_ci                Self { bits: self.bits ^ other.bits }
75174522d2cSopenharmony_ci            }
75274522d2cSopenharmony_ci        }
75374522d2cSopenharmony_ci
75474522d2cSopenharmony_ci        impl $crate::_core::ops::BitXorAssign for $BitFlags {
75574522d2cSopenharmony_ci            /// Toggles the set of flags.
75674522d2cSopenharmony_ci            #[inline]
75774522d2cSopenharmony_ci            fn bitxor_assign(&mut self, other: Self) {
75874522d2cSopenharmony_ci                self.bits ^= other.bits;
75974522d2cSopenharmony_ci            }
76074522d2cSopenharmony_ci        }
76174522d2cSopenharmony_ci
76274522d2cSopenharmony_ci        impl $crate::_core::ops::BitAnd for $BitFlags {
76374522d2cSopenharmony_ci            type Output = Self;
76474522d2cSopenharmony_ci
76574522d2cSopenharmony_ci            /// Returns the intersection between the two sets of flags.
76674522d2cSopenharmony_ci            #[inline]
76774522d2cSopenharmony_ci            fn bitand(self, other: Self) -> Self {
76874522d2cSopenharmony_ci                Self { bits: self.bits & other.bits }
76974522d2cSopenharmony_ci            }
77074522d2cSopenharmony_ci        }
77174522d2cSopenharmony_ci
77274522d2cSopenharmony_ci        impl $crate::_core::ops::BitAndAssign for $BitFlags {
77374522d2cSopenharmony_ci            /// Disables all flags disabled in the set.
77474522d2cSopenharmony_ci            #[inline]
77574522d2cSopenharmony_ci            fn bitand_assign(&mut self, other: Self) {
77674522d2cSopenharmony_ci                self.bits &= other.bits;
77774522d2cSopenharmony_ci            }
77874522d2cSopenharmony_ci        }
77974522d2cSopenharmony_ci
78074522d2cSopenharmony_ci        impl $crate::_core::ops::Sub for $BitFlags {
78174522d2cSopenharmony_ci            type Output = Self;
78274522d2cSopenharmony_ci
78374522d2cSopenharmony_ci            /// Returns the set difference of the two sets of flags.
78474522d2cSopenharmony_ci            #[inline]
78574522d2cSopenharmony_ci            fn sub(self, other: Self) -> Self {
78674522d2cSopenharmony_ci                Self { bits: self.bits & !other.bits }
78774522d2cSopenharmony_ci            }
78874522d2cSopenharmony_ci        }
78974522d2cSopenharmony_ci
79074522d2cSopenharmony_ci        impl $crate::_core::ops::SubAssign for $BitFlags {
79174522d2cSopenharmony_ci            /// Disables all flags enabled in the set.
79274522d2cSopenharmony_ci            #[inline]
79374522d2cSopenharmony_ci            fn sub_assign(&mut self, other: Self) {
79474522d2cSopenharmony_ci                self.bits &= !other.bits;
79574522d2cSopenharmony_ci            }
79674522d2cSopenharmony_ci        }
79774522d2cSopenharmony_ci
79874522d2cSopenharmony_ci        impl $crate::_core::ops::Not for $BitFlags {
79974522d2cSopenharmony_ci            type Output = Self;
80074522d2cSopenharmony_ci
80174522d2cSopenharmony_ci            /// Returns the complement of this set of flags.
80274522d2cSopenharmony_ci            #[inline]
80374522d2cSopenharmony_ci            fn not(self) -> Self {
80474522d2cSopenharmony_ci                Self { bits: !self.bits } & Self::all()
80574522d2cSopenharmony_ci            }
80674522d2cSopenharmony_ci        }
80774522d2cSopenharmony_ci
80874522d2cSopenharmony_ci        impl $crate::_core::iter::Extend<$BitFlags> for $BitFlags {
80974522d2cSopenharmony_ci            fn extend<T: $crate::_core::iter::IntoIterator<Item=Self>>(&mut self, iterator: T) {
81074522d2cSopenharmony_ci                for item in iterator {
81174522d2cSopenharmony_ci                    self.insert(item)
81274522d2cSopenharmony_ci                }
81374522d2cSopenharmony_ci            }
81474522d2cSopenharmony_ci        }
81574522d2cSopenharmony_ci
81674522d2cSopenharmony_ci        impl $crate::_core::iter::FromIterator<$BitFlags> for $BitFlags {
81774522d2cSopenharmony_ci            fn from_iter<T: $crate::_core::iter::IntoIterator<Item=Self>>(iterator: T) -> Self {
81874522d2cSopenharmony_ci                let mut result = Self::empty();
81974522d2cSopenharmony_ci                result.extend(iterator);
82074522d2cSopenharmony_ci                result
82174522d2cSopenharmony_ci            }
82274522d2cSopenharmony_ci        }
82374522d2cSopenharmony_ci    };
82474522d2cSopenharmony_ci
82574522d2cSopenharmony_ci    // Every attribute that the user writes on a const is applied to the
82674522d2cSopenharmony_ci    // corresponding const that we generate, but within the implementation of
82774522d2cSopenharmony_ci    // Debug and all() we want to ignore everything but #[cfg] attributes. In
82874522d2cSopenharmony_ci    // particular, including a #[deprecated] attribute on those items would fail
82974522d2cSopenharmony_ci    // to compile.
83074522d2cSopenharmony_ci    // https://github.com/bitflags/bitflags/issues/109
83174522d2cSopenharmony_ci    //
83274522d2cSopenharmony_ci    // Input:
83374522d2cSopenharmony_ci    //
83474522d2cSopenharmony_ci    //     ? #[cfg(feature = "advanced")]
83574522d2cSopenharmony_ci    //     ? #[deprecated(note = "Use something else.")]
83674522d2cSopenharmony_ci    //     ? #[doc = r"High quality documentation."]
83774522d2cSopenharmony_ci    //     fn f() -> i32 { /* ... */ }
83874522d2cSopenharmony_ci    //
83974522d2cSopenharmony_ci    // Output:
84074522d2cSopenharmony_ci    //
84174522d2cSopenharmony_ci    //     #[cfg(feature = "advanced")]
84274522d2cSopenharmony_ci    //     fn f() -> i32 { /* ... */ }
84374522d2cSopenharmony_ci    (
84474522d2cSopenharmony_ci        $(#[$filtered:meta])*
84574522d2cSopenharmony_ci        ? #[cfg $($cfgargs:tt)*]
84674522d2cSopenharmony_ci        $(? #[$rest:ident $($restargs:tt)*])*
84774522d2cSopenharmony_ci        fn $($item:tt)*
84874522d2cSopenharmony_ci    ) => {
84974522d2cSopenharmony_ci        __impl_bitflags! {
85074522d2cSopenharmony_ci            $(#[$filtered])*
85174522d2cSopenharmony_ci            #[cfg $($cfgargs)*]
85274522d2cSopenharmony_ci            $(? #[$rest $($restargs)*])*
85374522d2cSopenharmony_ci            fn $($item)*
85474522d2cSopenharmony_ci        }
85574522d2cSopenharmony_ci    };
85674522d2cSopenharmony_ci    (
85774522d2cSopenharmony_ci        $(#[$filtered:meta])*
85874522d2cSopenharmony_ci        // $next != `cfg`
85974522d2cSopenharmony_ci        ? #[$next:ident $($nextargs:tt)*]
86074522d2cSopenharmony_ci        $(? #[$rest:ident $($restargs:tt)*])*
86174522d2cSopenharmony_ci        fn $($item:tt)*
86274522d2cSopenharmony_ci    ) => {
86374522d2cSopenharmony_ci        __impl_bitflags! {
86474522d2cSopenharmony_ci            $(#[$filtered])*
86574522d2cSopenharmony_ci            // $next filtered out
86674522d2cSopenharmony_ci            $(? #[$rest $($restargs)*])*
86774522d2cSopenharmony_ci            fn $($item)*
86874522d2cSopenharmony_ci        }
86974522d2cSopenharmony_ci    };
87074522d2cSopenharmony_ci    (
87174522d2cSopenharmony_ci        $(#[$filtered:meta])*
87274522d2cSopenharmony_ci        fn $($item:tt)*
87374522d2cSopenharmony_ci    ) => {
87474522d2cSopenharmony_ci        $(#[$filtered])*
87574522d2cSopenharmony_ci        fn $($item)*
87674522d2cSopenharmony_ci    };
87774522d2cSopenharmony_ci
87874522d2cSopenharmony_ci    // Every attribute that the user writes on a const is applied to the
87974522d2cSopenharmony_ci    // corresponding const that we generate, but within the implementation of
88074522d2cSopenharmony_ci    // Debug and all() we want to ignore everything but #[cfg] attributes. In
88174522d2cSopenharmony_ci    // particular, including a #[deprecated] attribute on those items would fail
88274522d2cSopenharmony_ci    // to compile.
88374522d2cSopenharmony_ci    // https://github.com/bitflags/bitflags/issues/109
88474522d2cSopenharmony_ci    //
88574522d2cSopenharmony_ci    // const version
88674522d2cSopenharmony_ci    //
88774522d2cSopenharmony_ci    // Input:
88874522d2cSopenharmony_ci    //
88974522d2cSopenharmony_ci    //     ? #[cfg(feature = "advanced")]
89074522d2cSopenharmony_ci    //     ? #[deprecated(note = "Use something else.")]
89174522d2cSopenharmony_ci    //     ? #[doc = r"High quality documentation."]
89274522d2cSopenharmony_ci    //     const f: i32 { /* ... */ }
89374522d2cSopenharmony_ci    //
89474522d2cSopenharmony_ci    // Output:
89574522d2cSopenharmony_ci    //
89674522d2cSopenharmony_ci    //     #[cfg(feature = "advanced")]
89774522d2cSopenharmony_ci    //     const f: i32 { /* ... */ }
89874522d2cSopenharmony_ci    (
89974522d2cSopenharmony_ci        $(#[$filtered:meta])*
90074522d2cSopenharmony_ci        ? #[cfg $($cfgargs:tt)*]
90174522d2cSopenharmony_ci        $(? #[$rest:ident $($restargs:tt)*])*
90274522d2cSopenharmony_ci        const $($item:tt)*
90374522d2cSopenharmony_ci    ) => {
90474522d2cSopenharmony_ci        __impl_bitflags! {
90574522d2cSopenharmony_ci            $(#[$filtered])*
90674522d2cSopenharmony_ci            #[cfg $($cfgargs)*]
90774522d2cSopenharmony_ci            $(? #[$rest $($restargs)*])*
90874522d2cSopenharmony_ci            const $($item)*
90974522d2cSopenharmony_ci        }
91074522d2cSopenharmony_ci    };
91174522d2cSopenharmony_ci    (
91274522d2cSopenharmony_ci        $(#[$filtered:meta])*
91374522d2cSopenharmony_ci        // $next != `cfg`
91474522d2cSopenharmony_ci        ? #[$next:ident $($nextargs:tt)*]
91574522d2cSopenharmony_ci        $(? #[$rest:ident $($restargs:tt)*])*
91674522d2cSopenharmony_ci        const $($item:tt)*
91774522d2cSopenharmony_ci    ) => {
91874522d2cSopenharmony_ci        __impl_bitflags! {
91974522d2cSopenharmony_ci            $(#[$filtered])*
92074522d2cSopenharmony_ci            // $next filtered out
92174522d2cSopenharmony_ci            $(? #[$rest $($restargs)*])*
92274522d2cSopenharmony_ci            const $($item)*
92374522d2cSopenharmony_ci        }
92474522d2cSopenharmony_ci    };
92574522d2cSopenharmony_ci    (
92674522d2cSopenharmony_ci        $(#[$filtered:meta])*
92774522d2cSopenharmony_ci        const $($item:tt)*
92874522d2cSopenharmony_ci    ) => {
92974522d2cSopenharmony_ci        $(#[$filtered])*
93074522d2cSopenharmony_ci        const $($item)*
93174522d2cSopenharmony_ci    };
93274522d2cSopenharmony_ci}
93374522d2cSopenharmony_ci
93474522d2cSopenharmony_ci#[cfg(feature = "example_generated")]
93574522d2cSopenharmony_cipub mod example_generated;
93674522d2cSopenharmony_ci
93774522d2cSopenharmony_ci#[cfg(test)]
93874522d2cSopenharmony_cimod tests {
93974522d2cSopenharmony_ci    use std::collections::hash_map::DefaultHasher;
94074522d2cSopenharmony_ci    use std::hash::{Hash, Hasher};
94174522d2cSopenharmony_ci
94274522d2cSopenharmony_ci    bitflags! {
94374522d2cSopenharmony_ci        #[doc = "> The first principle is that you must not fool yourself — and"]
94474522d2cSopenharmony_ci        #[doc = "> you are the easiest person to fool."]
94574522d2cSopenharmony_ci        #[doc = "> "]
94674522d2cSopenharmony_ci        #[doc = "> - Richard Feynman"]
94774522d2cSopenharmony_ci        #[derive(Default)]
94874522d2cSopenharmony_ci        struct Flags: u32 {
94974522d2cSopenharmony_ci            const A = 0b00000001;
95074522d2cSopenharmony_ci            #[doc = "<pcwalton> macros are way better at generating code than trans is"]
95174522d2cSopenharmony_ci            const B = 0b00000010;
95274522d2cSopenharmony_ci            const C = 0b00000100;
95374522d2cSopenharmony_ci            #[doc = "* cmr bed"]
95474522d2cSopenharmony_ci            #[doc = "* strcat table"]
95574522d2cSopenharmony_ci            #[doc = "<strcat> wait what?"]
95674522d2cSopenharmony_ci            const ABC = Self::A.bits | Self::B.bits | Self::C.bits;
95774522d2cSopenharmony_ci        }
95874522d2cSopenharmony_ci
95974522d2cSopenharmony_ci        struct _CfgFlags: u32 {
96074522d2cSopenharmony_ci            #[cfg(unix)]
96174522d2cSopenharmony_ci            const _CFG_A = 0b01;
96274522d2cSopenharmony_ci            #[cfg(windows)]
96374522d2cSopenharmony_ci            const _CFG_B = 0b01;
96474522d2cSopenharmony_ci            #[cfg(unix)]
96574522d2cSopenharmony_ci            const _CFG_C = Self::_CFG_A.bits | 0b10;
96674522d2cSopenharmony_ci        }
96774522d2cSopenharmony_ci
96874522d2cSopenharmony_ci        struct AnotherSetOfFlags: i8 {
96974522d2cSopenharmony_ci            const ANOTHER_FLAG = -1_i8;
97074522d2cSopenharmony_ci        }
97174522d2cSopenharmony_ci
97274522d2cSopenharmony_ci        struct LongFlags: u32 {
97374522d2cSopenharmony_ci            const LONG_A = 0b1111111111111111;
97474522d2cSopenharmony_ci        }
97574522d2cSopenharmony_ci    }
97674522d2cSopenharmony_ci
97774522d2cSopenharmony_ci    bitflags! {
97874522d2cSopenharmony_ci        struct EmptyFlags: u32 {
97974522d2cSopenharmony_ci        }
98074522d2cSopenharmony_ci    }
98174522d2cSopenharmony_ci
98274522d2cSopenharmony_ci    #[test]
98374522d2cSopenharmony_ci    fn test_bits() {
98474522d2cSopenharmony_ci        assert_eq!(Flags::empty().bits(), 0b00000000);
98574522d2cSopenharmony_ci        assert_eq!(Flags::A.bits(), 0b00000001);
98674522d2cSopenharmony_ci        assert_eq!(Flags::ABC.bits(), 0b00000111);
98774522d2cSopenharmony_ci
98874522d2cSopenharmony_ci        assert_eq!(AnotherSetOfFlags::empty().bits(), 0b00);
98974522d2cSopenharmony_ci        assert_eq!(AnotherSetOfFlags::ANOTHER_FLAG.bits(), !0_i8);
99074522d2cSopenharmony_ci
99174522d2cSopenharmony_ci        assert_eq!(EmptyFlags::empty().bits(), 0b00000000);
99274522d2cSopenharmony_ci    }
99374522d2cSopenharmony_ci
99474522d2cSopenharmony_ci    #[test]
99574522d2cSopenharmony_ci    fn test_from_bits() {
99674522d2cSopenharmony_ci        assert_eq!(Flags::from_bits(0), Some(Flags::empty()));
99774522d2cSopenharmony_ci        assert_eq!(Flags::from_bits(0b1), Some(Flags::A));
99874522d2cSopenharmony_ci        assert_eq!(Flags::from_bits(0b10), Some(Flags::B));
99974522d2cSopenharmony_ci        assert_eq!(Flags::from_bits(0b11), Some(Flags::A | Flags::B));
100074522d2cSopenharmony_ci        assert_eq!(Flags::from_bits(0b1000), None);
100174522d2cSopenharmony_ci
100274522d2cSopenharmony_ci        assert_eq!(
100374522d2cSopenharmony_ci            AnotherSetOfFlags::from_bits(!0_i8),
100474522d2cSopenharmony_ci            Some(AnotherSetOfFlags::ANOTHER_FLAG)
100574522d2cSopenharmony_ci        );
100674522d2cSopenharmony_ci
100774522d2cSopenharmony_ci        assert_eq!(EmptyFlags::from_bits(0), Some(EmptyFlags::empty()));
100874522d2cSopenharmony_ci        assert_eq!(EmptyFlags::from_bits(0b1), None);
100974522d2cSopenharmony_ci    }
101074522d2cSopenharmony_ci
101174522d2cSopenharmony_ci    #[test]
101274522d2cSopenharmony_ci    fn test_from_bits_truncate() {
101374522d2cSopenharmony_ci        assert_eq!(Flags::from_bits_truncate(0), Flags::empty());
101474522d2cSopenharmony_ci        assert_eq!(Flags::from_bits_truncate(0b1), Flags::A);
101574522d2cSopenharmony_ci        assert_eq!(Flags::from_bits_truncate(0b10), Flags::B);
101674522d2cSopenharmony_ci        assert_eq!(Flags::from_bits_truncate(0b11), (Flags::A | Flags::B));
101774522d2cSopenharmony_ci        assert_eq!(Flags::from_bits_truncate(0b1000), Flags::empty());
101874522d2cSopenharmony_ci        assert_eq!(Flags::from_bits_truncate(0b1001), Flags::A);
101974522d2cSopenharmony_ci
102074522d2cSopenharmony_ci        assert_eq!(
102174522d2cSopenharmony_ci            AnotherSetOfFlags::from_bits_truncate(0_i8),
102274522d2cSopenharmony_ci            AnotherSetOfFlags::empty()
102374522d2cSopenharmony_ci        );
102474522d2cSopenharmony_ci
102574522d2cSopenharmony_ci        assert_eq!(EmptyFlags::from_bits_truncate(0), EmptyFlags::empty());
102674522d2cSopenharmony_ci        assert_eq!(EmptyFlags::from_bits_truncate(0b1), EmptyFlags::empty());
102774522d2cSopenharmony_ci    }
102874522d2cSopenharmony_ci
102974522d2cSopenharmony_ci    #[test]
103074522d2cSopenharmony_ci    fn test_from_bits_unchecked() {
103174522d2cSopenharmony_ci        let extra = unsafe { Flags::from_bits_unchecked(0b1000) };
103274522d2cSopenharmony_ci        assert_eq!(unsafe { Flags::from_bits_unchecked(0) }, Flags::empty());
103374522d2cSopenharmony_ci        assert_eq!(unsafe { Flags::from_bits_unchecked(0b1) }, Flags::A);
103474522d2cSopenharmony_ci        assert_eq!(unsafe { Flags::from_bits_unchecked(0b10) }, Flags::B);
103574522d2cSopenharmony_ci
103674522d2cSopenharmony_ci        assert_eq!(
103774522d2cSopenharmony_ci            unsafe { Flags::from_bits_unchecked(0b11) },
103874522d2cSopenharmony_ci            (Flags::A | Flags::B)
103974522d2cSopenharmony_ci        );
104074522d2cSopenharmony_ci        assert_eq!(
104174522d2cSopenharmony_ci            unsafe { Flags::from_bits_unchecked(0b1000) },
104274522d2cSopenharmony_ci            (extra | Flags::empty())
104374522d2cSopenharmony_ci        );
104474522d2cSopenharmony_ci        assert_eq!(
104574522d2cSopenharmony_ci            unsafe { Flags::from_bits_unchecked(0b1001) },
104674522d2cSopenharmony_ci            (extra | Flags::A)
104774522d2cSopenharmony_ci        );
104874522d2cSopenharmony_ci
104974522d2cSopenharmony_ci        let extra = unsafe { EmptyFlags::from_bits_unchecked(0b1000) };
105074522d2cSopenharmony_ci        assert_eq!(
105174522d2cSopenharmony_ci            unsafe { EmptyFlags::from_bits_unchecked(0b1000) },
105274522d2cSopenharmony_ci            (extra | EmptyFlags::empty())
105374522d2cSopenharmony_ci        );
105474522d2cSopenharmony_ci    }
105574522d2cSopenharmony_ci
105674522d2cSopenharmony_ci    #[test]
105774522d2cSopenharmony_ci    fn test_is_empty() {
105874522d2cSopenharmony_ci        assert!(Flags::empty().is_empty());
105974522d2cSopenharmony_ci        assert!(!Flags::A.is_empty());
106074522d2cSopenharmony_ci        assert!(!Flags::ABC.is_empty());
106174522d2cSopenharmony_ci
106274522d2cSopenharmony_ci        assert!(!AnotherSetOfFlags::ANOTHER_FLAG.is_empty());
106374522d2cSopenharmony_ci
106474522d2cSopenharmony_ci        assert!(EmptyFlags::empty().is_empty());
106574522d2cSopenharmony_ci        assert!(EmptyFlags::all().is_empty());
106674522d2cSopenharmony_ci    }
106774522d2cSopenharmony_ci
106874522d2cSopenharmony_ci    #[test]
106974522d2cSopenharmony_ci    fn test_is_all() {
107074522d2cSopenharmony_ci        assert!(Flags::all().is_all());
107174522d2cSopenharmony_ci        assert!(!Flags::A.is_all());
107274522d2cSopenharmony_ci        assert!(Flags::ABC.is_all());
107374522d2cSopenharmony_ci
107474522d2cSopenharmony_ci        let extra = unsafe { Flags::from_bits_unchecked(0b1000) };
107574522d2cSopenharmony_ci        assert!(!extra.is_all());
107674522d2cSopenharmony_ci        assert!(!(Flags::A | extra).is_all());
107774522d2cSopenharmony_ci        assert!((Flags::ABC | extra).is_all());
107874522d2cSopenharmony_ci
107974522d2cSopenharmony_ci        assert!(AnotherSetOfFlags::ANOTHER_FLAG.is_all());
108074522d2cSopenharmony_ci
108174522d2cSopenharmony_ci        assert!(EmptyFlags::all().is_all());
108274522d2cSopenharmony_ci        assert!(EmptyFlags::empty().is_all());
108374522d2cSopenharmony_ci    }
108474522d2cSopenharmony_ci
108574522d2cSopenharmony_ci    #[test]
108674522d2cSopenharmony_ci    fn test_two_empties_do_not_intersect() {
108774522d2cSopenharmony_ci        let e1 = Flags::empty();
108874522d2cSopenharmony_ci        let e2 = Flags::empty();
108974522d2cSopenharmony_ci        assert!(!e1.intersects(e2));
109074522d2cSopenharmony_ci
109174522d2cSopenharmony_ci        assert!(AnotherSetOfFlags::ANOTHER_FLAG.intersects(AnotherSetOfFlags::ANOTHER_FLAG));
109274522d2cSopenharmony_ci    }
109374522d2cSopenharmony_ci
109474522d2cSopenharmony_ci    #[test]
109574522d2cSopenharmony_ci    fn test_empty_does_not_intersect_with_full() {
109674522d2cSopenharmony_ci        let e1 = Flags::empty();
109774522d2cSopenharmony_ci        let e2 = Flags::ABC;
109874522d2cSopenharmony_ci        assert!(!e1.intersects(e2));
109974522d2cSopenharmony_ci    }
110074522d2cSopenharmony_ci
110174522d2cSopenharmony_ci    #[test]
110274522d2cSopenharmony_ci    fn test_disjoint_intersects() {
110374522d2cSopenharmony_ci        let e1 = Flags::A;
110474522d2cSopenharmony_ci        let e2 = Flags::B;
110574522d2cSopenharmony_ci        assert!(!e1.intersects(e2));
110674522d2cSopenharmony_ci    }
110774522d2cSopenharmony_ci
110874522d2cSopenharmony_ci    #[test]
110974522d2cSopenharmony_ci    fn test_overlapping_intersects() {
111074522d2cSopenharmony_ci        let e1 = Flags::A;
111174522d2cSopenharmony_ci        let e2 = Flags::A | Flags::B;
111274522d2cSopenharmony_ci        assert!(e1.intersects(e2));
111374522d2cSopenharmony_ci    }
111474522d2cSopenharmony_ci
111574522d2cSopenharmony_ci    #[test]
111674522d2cSopenharmony_ci    fn test_contains() {
111774522d2cSopenharmony_ci        let e1 = Flags::A;
111874522d2cSopenharmony_ci        let e2 = Flags::A | Flags::B;
111974522d2cSopenharmony_ci        assert!(!e1.contains(e2));
112074522d2cSopenharmony_ci        assert!(e2.contains(e1));
112174522d2cSopenharmony_ci        assert!(Flags::ABC.contains(e2));
112274522d2cSopenharmony_ci
112374522d2cSopenharmony_ci        assert!(AnotherSetOfFlags::ANOTHER_FLAG.contains(AnotherSetOfFlags::ANOTHER_FLAG));
112474522d2cSopenharmony_ci
112574522d2cSopenharmony_ci        assert!(EmptyFlags::empty().contains(EmptyFlags::empty()));
112674522d2cSopenharmony_ci    }
112774522d2cSopenharmony_ci
112874522d2cSopenharmony_ci    #[test]
112974522d2cSopenharmony_ci    fn test_insert() {
113074522d2cSopenharmony_ci        let mut e1 = Flags::A;
113174522d2cSopenharmony_ci        let e2 = Flags::A | Flags::B;
113274522d2cSopenharmony_ci        e1.insert(e2);
113374522d2cSopenharmony_ci        assert_eq!(e1, e2);
113474522d2cSopenharmony_ci
113574522d2cSopenharmony_ci        let mut e3 = AnotherSetOfFlags::empty();
113674522d2cSopenharmony_ci        e3.insert(AnotherSetOfFlags::ANOTHER_FLAG);
113774522d2cSopenharmony_ci        assert_eq!(e3, AnotherSetOfFlags::ANOTHER_FLAG);
113874522d2cSopenharmony_ci    }
113974522d2cSopenharmony_ci
114074522d2cSopenharmony_ci    #[test]
114174522d2cSopenharmony_ci    fn test_remove() {
114274522d2cSopenharmony_ci        let mut e1 = Flags::A | Flags::B;
114374522d2cSopenharmony_ci        let e2 = Flags::A | Flags::C;
114474522d2cSopenharmony_ci        e1.remove(e2);
114574522d2cSopenharmony_ci        assert_eq!(e1, Flags::B);
114674522d2cSopenharmony_ci
114774522d2cSopenharmony_ci        let mut e3 = AnotherSetOfFlags::ANOTHER_FLAG;
114874522d2cSopenharmony_ci        e3.remove(AnotherSetOfFlags::ANOTHER_FLAG);
114974522d2cSopenharmony_ci        assert_eq!(e3, AnotherSetOfFlags::empty());
115074522d2cSopenharmony_ci    }
115174522d2cSopenharmony_ci
115274522d2cSopenharmony_ci    #[test]
115374522d2cSopenharmony_ci    fn test_operators() {
115474522d2cSopenharmony_ci        let e1 = Flags::A | Flags::C;
115574522d2cSopenharmony_ci        let e2 = Flags::B | Flags::C;
115674522d2cSopenharmony_ci        assert_eq!((e1 | e2), Flags::ABC); // union
115774522d2cSopenharmony_ci        assert_eq!((e1 & e2), Flags::C); // intersection
115874522d2cSopenharmony_ci        assert_eq!((e1 - e2), Flags::A); // set difference
115974522d2cSopenharmony_ci        assert_eq!(!e2, Flags::A); // set complement
116074522d2cSopenharmony_ci        assert_eq!(e1 ^ e2, Flags::A | Flags::B); // toggle
116174522d2cSopenharmony_ci        let mut e3 = e1;
116274522d2cSopenharmony_ci        e3.toggle(e2);
116374522d2cSopenharmony_ci        assert_eq!(e3, Flags::A | Flags::B);
116474522d2cSopenharmony_ci
116574522d2cSopenharmony_ci        let mut m4 = AnotherSetOfFlags::empty();
116674522d2cSopenharmony_ci        m4.toggle(AnotherSetOfFlags::empty());
116774522d2cSopenharmony_ci        assert_eq!(m4, AnotherSetOfFlags::empty());
116874522d2cSopenharmony_ci    }
116974522d2cSopenharmony_ci
117074522d2cSopenharmony_ci    #[test]
117174522d2cSopenharmony_ci    fn test_operators_unchecked() {
117274522d2cSopenharmony_ci        let extra = unsafe { Flags::from_bits_unchecked(0b1000) };
117374522d2cSopenharmony_ci        let e1 = Flags::A | Flags::C | extra;
117474522d2cSopenharmony_ci        let e2 = Flags::B | Flags::C;
117574522d2cSopenharmony_ci        assert_eq!((e1 | e2), (Flags::ABC | extra)); // union
117674522d2cSopenharmony_ci        assert_eq!((e1 & e2), Flags::C); // intersection
117774522d2cSopenharmony_ci        assert_eq!((e1 - e2), (Flags::A | extra)); // set difference
117874522d2cSopenharmony_ci        assert_eq!(!e2, Flags::A); // set complement
117974522d2cSopenharmony_ci        assert_eq!(!e1, Flags::B); // set complement
118074522d2cSopenharmony_ci        assert_eq!(e1 ^ e2, Flags::A | Flags::B | extra); // toggle
118174522d2cSopenharmony_ci        let mut e3 = e1;
118274522d2cSopenharmony_ci        e3.toggle(e2);
118374522d2cSopenharmony_ci        assert_eq!(e3, Flags::A | Flags::B | extra);
118474522d2cSopenharmony_ci    }
118574522d2cSopenharmony_ci
118674522d2cSopenharmony_ci    #[test]
118774522d2cSopenharmony_ci    fn test_set_ops_basic() {
118874522d2cSopenharmony_ci        let ab = Flags::A.union(Flags::B);
118974522d2cSopenharmony_ci        let ac = Flags::A.union(Flags::C);
119074522d2cSopenharmony_ci        let bc = Flags::B.union(Flags::C);
119174522d2cSopenharmony_ci        assert_eq!(ab.bits, 0b011);
119274522d2cSopenharmony_ci        assert_eq!(bc.bits, 0b110);
119374522d2cSopenharmony_ci        assert_eq!(ac.bits, 0b101);
119474522d2cSopenharmony_ci
119574522d2cSopenharmony_ci        assert_eq!(ab, Flags::B.union(Flags::A));
119674522d2cSopenharmony_ci        assert_eq!(ac, Flags::C.union(Flags::A));
119774522d2cSopenharmony_ci        assert_eq!(bc, Flags::C.union(Flags::B));
119874522d2cSopenharmony_ci
119974522d2cSopenharmony_ci        assert_eq!(ac, Flags::A | Flags::C);
120074522d2cSopenharmony_ci        assert_eq!(bc, Flags::B | Flags::C);
120174522d2cSopenharmony_ci        assert_eq!(ab.union(bc), Flags::ABC);
120274522d2cSopenharmony_ci
120374522d2cSopenharmony_ci        assert_eq!(ac, Flags::A | Flags::C);
120474522d2cSopenharmony_ci        assert_eq!(bc, Flags::B | Flags::C);
120574522d2cSopenharmony_ci
120674522d2cSopenharmony_ci        assert_eq!(ac.union(bc), ac | bc);
120774522d2cSopenharmony_ci        assert_eq!(ac.union(bc), Flags::ABC);
120874522d2cSopenharmony_ci        assert_eq!(bc.union(ac), Flags::ABC);
120974522d2cSopenharmony_ci
121074522d2cSopenharmony_ci        assert_eq!(ac.intersection(bc), ac & bc);
121174522d2cSopenharmony_ci        assert_eq!(ac.intersection(bc), Flags::C);
121274522d2cSopenharmony_ci        assert_eq!(bc.intersection(ac), Flags::C);
121374522d2cSopenharmony_ci
121474522d2cSopenharmony_ci        assert_eq!(ac.difference(bc), ac - bc);
121574522d2cSopenharmony_ci        assert_eq!(bc.difference(ac), bc - ac);
121674522d2cSopenharmony_ci        assert_eq!(ac.difference(bc), Flags::A);
121774522d2cSopenharmony_ci        assert_eq!(bc.difference(ac), Flags::B);
121874522d2cSopenharmony_ci
121974522d2cSopenharmony_ci        assert_eq!(bc.complement(), !bc);
122074522d2cSopenharmony_ci        assert_eq!(bc.complement(), Flags::A);
122174522d2cSopenharmony_ci        assert_eq!(ac.symmetric_difference(bc), Flags::A.union(Flags::B));
122274522d2cSopenharmony_ci        assert_eq!(bc.symmetric_difference(ac), Flags::A.union(Flags::B));
122374522d2cSopenharmony_ci    }
122474522d2cSopenharmony_ci
122574522d2cSopenharmony_ci    #[test]
122674522d2cSopenharmony_ci    fn test_set_ops_const() {
122774522d2cSopenharmony_ci        // These just test that these compile and don't cause use-site panics
122874522d2cSopenharmony_ci        // (would be possible if we had some sort of UB)
122974522d2cSopenharmony_ci        const INTERSECT: Flags = Flags::all().intersection(Flags::C);
123074522d2cSopenharmony_ci        const UNION: Flags = Flags::A.union(Flags::C);
123174522d2cSopenharmony_ci        const DIFFERENCE: Flags = Flags::all().difference(Flags::A);
123274522d2cSopenharmony_ci        const COMPLEMENT: Flags = Flags::C.complement();
123374522d2cSopenharmony_ci        const SYM_DIFFERENCE: Flags = UNION.symmetric_difference(DIFFERENCE);
123474522d2cSopenharmony_ci        assert_eq!(INTERSECT, Flags::C);
123574522d2cSopenharmony_ci        assert_eq!(UNION, Flags::A | Flags::C);
123674522d2cSopenharmony_ci        assert_eq!(DIFFERENCE, Flags::all() - Flags::A);
123774522d2cSopenharmony_ci        assert_eq!(COMPLEMENT, !Flags::C);
123874522d2cSopenharmony_ci        assert_eq!(SYM_DIFFERENCE, (Flags::A | Flags::C) ^ (Flags::all() - Flags::A));
123974522d2cSopenharmony_ci    }
124074522d2cSopenharmony_ci
124174522d2cSopenharmony_ci    #[test]
124274522d2cSopenharmony_ci    fn test_set_ops_unchecked() {
124374522d2cSopenharmony_ci        let extra = unsafe { Flags::from_bits_unchecked(0b1000) };
124474522d2cSopenharmony_ci        let e1 = Flags::A.union(Flags::C).union(extra);
124574522d2cSopenharmony_ci        let e2 = Flags::B.union(Flags::C);
124674522d2cSopenharmony_ci        assert_eq!(e1.bits, 0b1101);
124774522d2cSopenharmony_ci        assert_eq!(e1.union(e2), (Flags::ABC | extra));
124874522d2cSopenharmony_ci        assert_eq!(e1.intersection(e2), Flags::C);
124974522d2cSopenharmony_ci        assert_eq!(e1.difference(e2), Flags::A | extra);
125074522d2cSopenharmony_ci        assert_eq!(e2.difference(e1), Flags::B);
125174522d2cSopenharmony_ci        assert_eq!(e2.complement(), Flags::A);
125274522d2cSopenharmony_ci        assert_eq!(e1.complement(), Flags::B);
125374522d2cSopenharmony_ci        assert_eq!(e1.symmetric_difference(e2), Flags::A | Flags::B | extra); // toggle
125474522d2cSopenharmony_ci    }
125574522d2cSopenharmony_ci
125674522d2cSopenharmony_ci    #[test]
125774522d2cSopenharmony_ci    fn test_set_ops_exhaustive() {
125874522d2cSopenharmony_ci        // Define a flag that contains gaps to help exercise edge-cases,
125974522d2cSopenharmony_ci        // especially around "unknown" flags (e.g. ones outside of `all()`
126074522d2cSopenharmony_ci        // `from_bits_unchecked`).
126174522d2cSopenharmony_ci        // - when lhs and rhs both have different sets of unknown flags.
126274522d2cSopenharmony_ci        // - unknown flags at both ends, and in the middle
126374522d2cSopenharmony_ci        // - cases with "gaps".
126474522d2cSopenharmony_ci        bitflags! {
126574522d2cSopenharmony_ci            struct Test: u16 {
126674522d2cSopenharmony_ci                // Intentionally no `A`
126774522d2cSopenharmony_ci                const B = 0b000000010;
126874522d2cSopenharmony_ci                // Intentionally no `C`
126974522d2cSopenharmony_ci                const D = 0b000001000;
127074522d2cSopenharmony_ci                const E = 0b000010000;
127174522d2cSopenharmony_ci                const F = 0b000100000;
127274522d2cSopenharmony_ci                const G = 0b001000000;
127374522d2cSopenharmony_ci                // Intentionally no `H`
127474522d2cSopenharmony_ci                const I = 0b100000000;
127574522d2cSopenharmony_ci            }
127674522d2cSopenharmony_ci        }
127774522d2cSopenharmony_ci        let iter_test_flags =
127874522d2cSopenharmony_ci            || (0..=0b111_1111_1111).map(|bits| unsafe { Test::from_bits_unchecked(bits) });
127974522d2cSopenharmony_ci
128074522d2cSopenharmony_ci        for a in iter_test_flags() {
128174522d2cSopenharmony_ci            assert_eq!(
128274522d2cSopenharmony_ci                a.complement(),
128374522d2cSopenharmony_ci                Test::from_bits_truncate(!a.bits),
128474522d2cSopenharmony_ci                "wrong result: !({:?})",
128574522d2cSopenharmony_ci                a,
128674522d2cSopenharmony_ci            );
128774522d2cSopenharmony_ci            assert_eq!(a.complement(), !a, "named != op: !({:?})", a);
128874522d2cSopenharmony_ci            for b in iter_test_flags() {
128974522d2cSopenharmony_ci                // Check that the named operations produce the expected bitwise
129074522d2cSopenharmony_ci                // values.
129174522d2cSopenharmony_ci                assert_eq!(
129274522d2cSopenharmony_ci                    a.union(b).bits,
129374522d2cSopenharmony_ci                    a.bits | b.bits,
129474522d2cSopenharmony_ci                    "wrong result: `{:?}` | `{:?}`",
129574522d2cSopenharmony_ci                    a,
129674522d2cSopenharmony_ci                    b,
129774522d2cSopenharmony_ci                );
129874522d2cSopenharmony_ci                assert_eq!(
129974522d2cSopenharmony_ci                    a.intersection(b).bits,
130074522d2cSopenharmony_ci                    a.bits & b.bits,
130174522d2cSopenharmony_ci                    "wrong result: `{:?}` & `{:?}`",
130274522d2cSopenharmony_ci                    a,
130374522d2cSopenharmony_ci                    b,
130474522d2cSopenharmony_ci                );
130574522d2cSopenharmony_ci                assert_eq!(
130674522d2cSopenharmony_ci                    a.symmetric_difference(b).bits,
130774522d2cSopenharmony_ci                    a.bits ^ b.bits,
130874522d2cSopenharmony_ci                    "wrong result: `{:?}` ^ `{:?}`",
130974522d2cSopenharmony_ci                    a,
131074522d2cSopenharmony_ci                    b,
131174522d2cSopenharmony_ci                );
131274522d2cSopenharmony_ci                assert_eq!(
131374522d2cSopenharmony_ci                    a.difference(b).bits,
131474522d2cSopenharmony_ci                    a.bits & !b.bits,
131574522d2cSopenharmony_ci                    "wrong result: `{:?}` - `{:?}`",
131674522d2cSopenharmony_ci                    a,
131774522d2cSopenharmony_ci                    b,
131874522d2cSopenharmony_ci                );
131974522d2cSopenharmony_ci                // Note: Difference is checked as both `a - b` and `b - a`
132074522d2cSopenharmony_ci                assert_eq!(
132174522d2cSopenharmony_ci                    b.difference(a).bits,
132274522d2cSopenharmony_ci                    b.bits & !a.bits,
132374522d2cSopenharmony_ci                    "wrong result: `{:?}` - `{:?}`",
132474522d2cSopenharmony_ci                    b,
132574522d2cSopenharmony_ci                    a,
132674522d2cSopenharmony_ci                );
132774522d2cSopenharmony_ci                // Check that the named set operations are equivalent to the
132874522d2cSopenharmony_ci                // bitwise equivalents
132974522d2cSopenharmony_ci                assert_eq!(a.union(b), a | b, "named != op: `{:?}` | `{:?}`", a, b,);
133074522d2cSopenharmony_ci                assert_eq!(
133174522d2cSopenharmony_ci                    a.intersection(b),
133274522d2cSopenharmony_ci                    a & b,
133374522d2cSopenharmony_ci                    "named != op: `{:?}` & `{:?}`",
133474522d2cSopenharmony_ci                    a,
133574522d2cSopenharmony_ci                    b,
133674522d2cSopenharmony_ci                );
133774522d2cSopenharmony_ci                assert_eq!(
133874522d2cSopenharmony_ci                    a.symmetric_difference(b),
133974522d2cSopenharmony_ci                    a ^ b,
134074522d2cSopenharmony_ci                    "named != op: `{:?}` ^ `{:?}`",
134174522d2cSopenharmony_ci                    a,
134274522d2cSopenharmony_ci                    b,
134374522d2cSopenharmony_ci                );
134474522d2cSopenharmony_ci                assert_eq!(a.difference(b), a - b, "named != op: `{:?}` - `{:?}`", a, b,);
134574522d2cSopenharmony_ci                // Note: Difference is checked as both `a - b` and `b - a`
134674522d2cSopenharmony_ci                assert_eq!(b.difference(a), b - a, "named != op: `{:?}` - `{:?}`", b, a,);
134774522d2cSopenharmony_ci                // Verify that the operations which should be symmetric are
134874522d2cSopenharmony_ci                // actually symmetric.
134974522d2cSopenharmony_ci                assert_eq!(a.union(b), b.union(a), "asymmetry: `{:?}` | `{:?}`", a, b,);
135074522d2cSopenharmony_ci                assert_eq!(
135174522d2cSopenharmony_ci                    a.intersection(b),
135274522d2cSopenharmony_ci                    b.intersection(a),
135374522d2cSopenharmony_ci                    "asymmetry: `{:?}` & `{:?}`",
135474522d2cSopenharmony_ci                    a,
135574522d2cSopenharmony_ci                    b,
135674522d2cSopenharmony_ci                );
135774522d2cSopenharmony_ci                assert_eq!(
135874522d2cSopenharmony_ci                    a.symmetric_difference(b),
135974522d2cSopenharmony_ci                    b.symmetric_difference(a),
136074522d2cSopenharmony_ci                    "asymmetry: `{:?}` ^ `{:?}`",
136174522d2cSopenharmony_ci                    a,
136274522d2cSopenharmony_ci                    b,
136374522d2cSopenharmony_ci                );
136474522d2cSopenharmony_ci            }
136574522d2cSopenharmony_ci        }
136674522d2cSopenharmony_ci    }
136774522d2cSopenharmony_ci
136874522d2cSopenharmony_ci    #[test]
136974522d2cSopenharmony_ci    fn test_set() {
137074522d2cSopenharmony_ci        let mut e1 = Flags::A | Flags::C;
137174522d2cSopenharmony_ci        e1.set(Flags::B, true);
137274522d2cSopenharmony_ci        e1.set(Flags::C, false);
137374522d2cSopenharmony_ci
137474522d2cSopenharmony_ci        assert_eq!(e1, Flags::A | Flags::B);
137574522d2cSopenharmony_ci    }
137674522d2cSopenharmony_ci
137774522d2cSopenharmony_ci    #[test]
137874522d2cSopenharmony_ci    fn test_assignment_operators() {
137974522d2cSopenharmony_ci        let mut m1 = Flags::empty();
138074522d2cSopenharmony_ci        let e1 = Flags::A | Flags::C;
138174522d2cSopenharmony_ci        // union
138274522d2cSopenharmony_ci        m1 |= Flags::A;
138374522d2cSopenharmony_ci        assert_eq!(m1, Flags::A);
138474522d2cSopenharmony_ci        // intersection
138574522d2cSopenharmony_ci        m1 &= e1;
138674522d2cSopenharmony_ci        assert_eq!(m1, Flags::A);
138774522d2cSopenharmony_ci        // set difference
138874522d2cSopenharmony_ci        m1 -= m1;
138974522d2cSopenharmony_ci        assert_eq!(m1, Flags::empty());
139074522d2cSopenharmony_ci        // toggle
139174522d2cSopenharmony_ci        m1 ^= e1;
139274522d2cSopenharmony_ci        assert_eq!(m1, e1);
139374522d2cSopenharmony_ci    }
139474522d2cSopenharmony_ci
139574522d2cSopenharmony_ci    #[test]
139674522d2cSopenharmony_ci    fn test_const_fn() {
139774522d2cSopenharmony_ci        const _M1: Flags = Flags::empty();
139874522d2cSopenharmony_ci
139974522d2cSopenharmony_ci        const M2: Flags = Flags::A;
140074522d2cSopenharmony_ci        assert_eq!(M2, Flags::A);
140174522d2cSopenharmony_ci
140274522d2cSopenharmony_ci        const M3: Flags = Flags::C;
140374522d2cSopenharmony_ci        assert_eq!(M3, Flags::C);
140474522d2cSopenharmony_ci    }
140574522d2cSopenharmony_ci
140674522d2cSopenharmony_ci    #[test]
140774522d2cSopenharmony_ci    fn test_extend() {
140874522d2cSopenharmony_ci        let mut flags;
140974522d2cSopenharmony_ci
141074522d2cSopenharmony_ci        flags = Flags::empty();
141174522d2cSopenharmony_ci        flags.extend([].iter().cloned());
141274522d2cSopenharmony_ci        assert_eq!(flags, Flags::empty());
141374522d2cSopenharmony_ci
141474522d2cSopenharmony_ci        flags = Flags::empty();
141574522d2cSopenharmony_ci        flags.extend([Flags::A, Flags::B].iter().cloned());
141674522d2cSopenharmony_ci        assert_eq!(flags, Flags::A | Flags::B);
141774522d2cSopenharmony_ci
141874522d2cSopenharmony_ci        flags = Flags::A;
141974522d2cSopenharmony_ci        flags.extend([Flags::A, Flags::B].iter().cloned());
142074522d2cSopenharmony_ci        assert_eq!(flags, Flags::A | Flags::B);
142174522d2cSopenharmony_ci
142274522d2cSopenharmony_ci        flags = Flags::B;
142374522d2cSopenharmony_ci        flags.extend([Flags::A, Flags::ABC].iter().cloned());
142474522d2cSopenharmony_ci        assert_eq!(flags, Flags::ABC);
142574522d2cSopenharmony_ci    }
142674522d2cSopenharmony_ci
142774522d2cSopenharmony_ci    #[test]
142874522d2cSopenharmony_ci    fn test_from_iterator() {
142974522d2cSopenharmony_ci        assert_eq!([].iter().cloned().collect::<Flags>(), Flags::empty());
143074522d2cSopenharmony_ci        assert_eq!(
143174522d2cSopenharmony_ci            [Flags::A, Flags::B].iter().cloned().collect::<Flags>(),
143274522d2cSopenharmony_ci            Flags::A | Flags::B
143374522d2cSopenharmony_ci        );
143474522d2cSopenharmony_ci        assert_eq!(
143574522d2cSopenharmony_ci            [Flags::A, Flags::ABC].iter().cloned().collect::<Flags>(),
143674522d2cSopenharmony_ci            Flags::ABC
143774522d2cSopenharmony_ci        );
143874522d2cSopenharmony_ci    }
143974522d2cSopenharmony_ci
144074522d2cSopenharmony_ci    #[test]
144174522d2cSopenharmony_ci    fn test_lt() {
144274522d2cSopenharmony_ci        let mut a = Flags::empty();
144374522d2cSopenharmony_ci        let mut b = Flags::empty();
144474522d2cSopenharmony_ci
144574522d2cSopenharmony_ci        assert!(!(a < b) && !(b < a));
144674522d2cSopenharmony_ci        b = Flags::B;
144774522d2cSopenharmony_ci        assert!(a < b);
144874522d2cSopenharmony_ci        a = Flags::C;
144974522d2cSopenharmony_ci        assert!(!(a < b) && b < a);
145074522d2cSopenharmony_ci        b = Flags::C | Flags::B;
145174522d2cSopenharmony_ci        assert!(a < b);
145274522d2cSopenharmony_ci    }
145374522d2cSopenharmony_ci
145474522d2cSopenharmony_ci    #[test]
145574522d2cSopenharmony_ci    fn test_ord() {
145674522d2cSopenharmony_ci        let mut a = Flags::empty();
145774522d2cSopenharmony_ci        let mut b = Flags::empty();
145874522d2cSopenharmony_ci
145974522d2cSopenharmony_ci        assert!(a <= b && a >= b);
146074522d2cSopenharmony_ci        a = Flags::A;
146174522d2cSopenharmony_ci        assert!(a > b && a >= b);
146274522d2cSopenharmony_ci        assert!(b < a && b <= a);
146374522d2cSopenharmony_ci        b = Flags::B;
146474522d2cSopenharmony_ci        assert!(b > a && b >= a);
146574522d2cSopenharmony_ci        assert!(a < b && a <= b);
146674522d2cSopenharmony_ci    }
146774522d2cSopenharmony_ci
146874522d2cSopenharmony_ci    fn hash<T: Hash>(t: &T) -> u64 {
146974522d2cSopenharmony_ci        let mut s = DefaultHasher::new();
147074522d2cSopenharmony_ci        t.hash(&mut s);
147174522d2cSopenharmony_ci        s.finish()
147274522d2cSopenharmony_ci    }
147374522d2cSopenharmony_ci
147474522d2cSopenharmony_ci    #[test]
147574522d2cSopenharmony_ci    fn test_hash() {
147674522d2cSopenharmony_ci        let mut x = Flags::empty();
147774522d2cSopenharmony_ci        let mut y = Flags::empty();
147874522d2cSopenharmony_ci        assert_eq!(hash(&x), hash(&y));
147974522d2cSopenharmony_ci        x = Flags::all();
148074522d2cSopenharmony_ci        y = Flags::ABC;
148174522d2cSopenharmony_ci        assert_eq!(hash(&x), hash(&y));
148274522d2cSopenharmony_ci    }
148374522d2cSopenharmony_ci
148474522d2cSopenharmony_ci    #[test]
148574522d2cSopenharmony_ci    fn test_default() {
148674522d2cSopenharmony_ci        assert_eq!(Flags::empty(), Flags::default());
148774522d2cSopenharmony_ci    }
148874522d2cSopenharmony_ci
148974522d2cSopenharmony_ci    #[test]
149074522d2cSopenharmony_ci    fn test_debug() {
149174522d2cSopenharmony_ci        assert_eq!(format!("{:?}", Flags::A | Flags::B), "A | B");
149274522d2cSopenharmony_ci        assert_eq!(format!("{:?}", Flags::empty()), "(empty)");
149374522d2cSopenharmony_ci        assert_eq!(format!("{:?}", Flags::ABC), "A | B | C | ABC");
149474522d2cSopenharmony_ci        let extra = unsafe { Flags::from_bits_unchecked(0xb8) };
149574522d2cSopenharmony_ci        assert_eq!(format!("{:?}", extra), "0xb8");
149674522d2cSopenharmony_ci        assert_eq!(format!("{:?}", Flags::A | extra), "A | 0xb8");
149774522d2cSopenharmony_ci
149874522d2cSopenharmony_ci        assert_eq!(
149974522d2cSopenharmony_ci            format!("{:?}", Flags::ABC | extra),
150074522d2cSopenharmony_ci            "A | B | C | ABC | 0xb8"
150174522d2cSopenharmony_ci        );
150274522d2cSopenharmony_ci
150374522d2cSopenharmony_ci        assert_eq!(format!("{:?}", EmptyFlags::empty()), "(empty)");
150474522d2cSopenharmony_ci    }
150574522d2cSopenharmony_ci
150674522d2cSopenharmony_ci    #[test]
150774522d2cSopenharmony_ci    fn test_binary() {
150874522d2cSopenharmony_ci        assert_eq!(format!("{:b}", Flags::ABC), "111");
150974522d2cSopenharmony_ci        assert_eq!(format!("{:#b}", Flags::ABC), "0b111");
151074522d2cSopenharmony_ci        let extra = unsafe { Flags::from_bits_unchecked(0b1010000) };
151174522d2cSopenharmony_ci        assert_eq!(format!("{:b}", Flags::ABC | extra), "1010111");
151274522d2cSopenharmony_ci        assert_eq!(format!("{:#b}", Flags::ABC | extra), "0b1010111");
151374522d2cSopenharmony_ci    }
151474522d2cSopenharmony_ci
151574522d2cSopenharmony_ci    #[test]
151674522d2cSopenharmony_ci    fn test_octal() {
151774522d2cSopenharmony_ci        assert_eq!(format!("{:o}", LongFlags::LONG_A), "177777");
151874522d2cSopenharmony_ci        assert_eq!(format!("{:#o}", LongFlags::LONG_A), "0o177777");
151974522d2cSopenharmony_ci        let extra = unsafe { LongFlags::from_bits_unchecked(0o5000000) };
152074522d2cSopenharmony_ci        assert_eq!(format!("{:o}", LongFlags::LONG_A | extra), "5177777");
152174522d2cSopenharmony_ci        assert_eq!(format!("{:#o}", LongFlags::LONG_A | extra), "0o5177777");
152274522d2cSopenharmony_ci    }
152374522d2cSopenharmony_ci
152474522d2cSopenharmony_ci    #[test]
152574522d2cSopenharmony_ci    fn test_lowerhex() {
152674522d2cSopenharmony_ci        assert_eq!(format!("{:x}", LongFlags::LONG_A), "ffff");
152774522d2cSopenharmony_ci        assert_eq!(format!("{:#x}", LongFlags::LONG_A), "0xffff");
152874522d2cSopenharmony_ci        let extra = unsafe { LongFlags::from_bits_unchecked(0xe00000) };
152974522d2cSopenharmony_ci        assert_eq!(format!("{:x}", LongFlags::LONG_A | extra), "e0ffff");
153074522d2cSopenharmony_ci        assert_eq!(format!("{:#x}", LongFlags::LONG_A | extra), "0xe0ffff");
153174522d2cSopenharmony_ci    }
153274522d2cSopenharmony_ci
153374522d2cSopenharmony_ci    #[test]
153474522d2cSopenharmony_ci    fn test_upperhex() {
153574522d2cSopenharmony_ci        assert_eq!(format!("{:X}", LongFlags::LONG_A), "FFFF");
153674522d2cSopenharmony_ci        assert_eq!(format!("{:#X}", LongFlags::LONG_A), "0xFFFF");
153774522d2cSopenharmony_ci        let extra = unsafe { LongFlags::from_bits_unchecked(0xe00000) };
153874522d2cSopenharmony_ci        assert_eq!(format!("{:X}", LongFlags::LONG_A | extra), "E0FFFF");
153974522d2cSopenharmony_ci        assert_eq!(format!("{:#X}", LongFlags::LONG_A | extra), "0xE0FFFF");
154074522d2cSopenharmony_ci    }
154174522d2cSopenharmony_ci
154274522d2cSopenharmony_ci    mod submodule {
154374522d2cSopenharmony_ci        bitflags! {
154474522d2cSopenharmony_ci            pub struct PublicFlags: i8 {
154574522d2cSopenharmony_ci                const X = 0;
154674522d2cSopenharmony_ci            }
154774522d2cSopenharmony_ci
154874522d2cSopenharmony_ci            struct PrivateFlags: i8 {
154974522d2cSopenharmony_ci                const Y = 0;
155074522d2cSopenharmony_ci            }
155174522d2cSopenharmony_ci        }
155274522d2cSopenharmony_ci
155374522d2cSopenharmony_ci        #[test]
155474522d2cSopenharmony_ci        fn test_private() {
155574522d2cSopenharmony_ci            let _ = PrivateFlags::Y;
155674522d2cSopenharmony_ci        }
155774522d2cSopenharmony_ci    }
155874522d2cSopenharmony_ci
155974522d2cSopenharmony_ci    #[test]
156074522d2cSopenharmony_ci    fn test_public() {
156174522d2cSopenharmony_ci        let _ = submodule::PublicFlags::X;
156274522d2cSopenharmony_ci    }
156374522d2cSopenharmony_ci
156474522d2cSopenharmony_ci    mod t1 {
156574522d2cSopenharmony_ci        mod foo {
156674522d2cSopenharmony_ci            pub type Bar = i32;
156774522d2cSopenharmony_ci        }
156874522d2cSopenharmony_ci
156974522d2cSopenharmony_ci        bitflags! {
157074522d2cSopenharmony_ci            /// baz
157174522d2cSopenharmony_ci            struct Flags: foo::Bar {
157274522d2cSopenharmony_ci                const A = 0b00000001;
157374522d2cSopenharmony_ci                #[cfg(foo)]
157474522d2cSopenharmony_ci                const B = 0b00000010;
157574522d2cSopenharmony_ci                #[cfg(foo)]
157674522d2cSopenharmony_ci                const C = 0b00000010;
157774522d2cSopenharmony_ci            }
157874522d2cSopenharmony_ci        }
157974522d2cSopenharmony_ci    }
158074522d2cSopenharmony_ci
158174522d2cSopenharmony_ci    #[test]
158274522d2cSopenharmony_ci    fn test_in_function() {
158374522d2cSopenharmony_ci        bitflags! {
158474522d2cSopenharmony_ci           struct Flags: u8 {
158574522d2cSopenharmony_ci                const A = 1;
158674522d2cSopenharmony_ci                #[cfg(any())] // false
158774522d2cSopenharmony_ci                const B = 2;
158874522d2cSopenharmony_ci            }
158974522d2cSopenharmony_ci        }
159074522d2cSopenharmony_ci        assert_eq!(Flags::all(), Flags::A);
159174522d2cSopenharmony_ci        assert_eq!(format!("{:?}", Flags::A), "A");
159274522d2cSopenharmony_ci    }
159374522d2cSopenharmony_ci
159474522d2cSopenharmony_ci    #[test]
159574522d2cSopenharmony_ci    fn test_deprecated() {
159674522d2cSopenharmony_ci        bitflags! {
159774522d2cSopenharmony_ci            pub struct TestFlags: u32 {
159874522d2cSopenharmony_ci                #[deprecated(note = "Use something else.")]
159974522d2cSopenharmony_ci                const ONE = 1;
160074522d2cSopenharmony_ci            }
160174522d2cSopenharmony_ci        }
160274522d2cSopenharmony_ci    }
160374522d2cSopenharmony_ci
160474522d2cSopenharmony_ci    #[test]
160574522d2cSopenharmony_ci    fn test_pub_crate() {
160674522d2cSopenharmony_ci        mod module {
160774522d2cSopenharmony_ci            bitflags! {
160874522d2cSopenharmony_ci                pub (crate) struct Test: u8 {
160974522d2cSopenharmony_ci                    const FOO = 1;
161074522d2cSopenharmony_ci                }
161174522d2cSopenharmony_ci            }
161274522d2cSopenharmony_ci        }
161374522d2cSopenharmony_ci
161474522d2cSopenharmony_ci        assert_eq!(module::Test::FOO.bits(), 1);
161574522d2cSopenharmony_ci    }
161674522d2cSopenharmony_ci
161774522d2cSopenharmony_ci    #[test]
161874522d2cSopenharmony_ci    fn test_pub_in_module() {
161974522d2cSopenharmony_ci        mod module {
162074522d2cSopenharmony_ci            mod submodule {
162174522d2cSopenharmony_ci                bitflags! {
162274522d2cSopenharmony_ci                    // `pub (in super)` means only the module `module` will
162374522d2cSopenharmony_ci                    // be able to access this.
162474522d2cSopenharmony_ci                    pub (in super) struct Test: u8 {
162574522d2cSopenharmony_ci                        const FOO = 1;
162674522d2cSopenharmony_ci                    }
162774522d2cSopenharmony_ci                }
162874522d2cSopenharmony_ci            }
162974522d2cSopenharmony_ci
163074522d2cSopenharmony_ci            mod test {
163174522d2cSopenharmony_ci                // Note: due to `pub (in super)`,
163274522d2cSopenharmony_ci                // this cannot be accessed directly by the testing code.
163374522d2cSopenharmony_ci                pub(super) fn value() -> u8 {
163474522d2cSopenharmony_ci                    super::submodule::Test::FOO.bits()
163574522d2cSopenharmony_ci                }
163674522d2cSopenharmony_ci            }
163774522d2cSopenharmony_ci
163874522d2cSopenharmony_ci            pub fn value() -> u8 {
163974522d2cSopenharmony_ci                test::value()
164074522d2cSopenharmony_ci            }
164174522d2cSopenharmony_ci        }
164274522d2cSopenharmony_ci
164374522d2cSopenharmony_ci        assert_eq!(module::value(), 1)
164474522d2cSopenharmony_ci    }
164574522d2cSopenharmony_ci
164674522d2cSopenharmony_ci    #[test]
164774522d2cSopenharmony_ci    fn test_zero_value_flags() {
164874522d2cSopenharmony_ci        bitflags! {
164974522d2cSopenharmony_ci            struct Flags: u32 {
165074522d2cSopenharmony_ci                const NONE = 0b0;
165174522d2cSopenharmony_ci                const SOME = 0b1;
165274522d2cSopenharmony_ci            }
165374522d2cSopenharmony_ci        }
165474522d2cSopenharmony_ci
165574522d2cSopenharmony_ci        assert!(Flags::empty().contains(Flags::NONE));
165674522d2cSopenharmony_ci        assert!(Flags::SOME.contains(Flags::NONE));
165774522d2cSopenharmony_ci        assert!(Flags::NONE.is_empty());
165874522d2cSopenharmony_ci
165974522d2cSopenharmony_ci        assert_eq!(format!("{:?}", Flags::empty()), "NONE");
166074522d2cSopenharmony_ci        assert_eq!(format!("{:?}", Flags::SOME), "SOME");
166174522d2cSopenharmony_ci    }
166274522d2cSopenharmony_ci
166374522d2cSopenharmony_ci    #[test]
166474522d2cSopenharmony_ci    fn test_empty_bitflags() {
166574522d2cSopenharmony_ci        bitflags! {}
166674522d2cSopenharmony_ci    }
166774522d2cSopenharmony_ci
166874522d2cSopenharmony_ci    #[test]
166974522d2cSopenharmony_ci    fn test_u128_bitflags() {
167074522d2cSopenharmony_ci        bitflags! {
167174522d2cSopenharmony_ci            struct Flags128: u128 {
167274522d2cSopenharmony_ci                const A = 0x0000_0000_0000_0000_0000_0000_0000_0001;
167374522d2cSopenharmony_ci                const B = 0x0000_0000_0000_1000_0000_0000_0000_0000;
167474522d2cSopenharmony_ci                const C = 0x8000_0000_0000_0000_0000_0000_0000_0000;
167574522d2cSopenharmony_ci                const ABC = Self::A.bits | Self::B.bits | Self::C.bits;
167674522d2cSopenharmony_ci            }
167774522d2cSopenharmony_ci        }
167874522d2cSopenharmony_ci
167974522d2cSopenharmony_ci        assert_eq!(Flags128::ABC, Flags128::A | Flags128::B | Flags128::C);
168074522d2cSopenharmony_ci        assert_eq!(Flags128::A.bits, 0x0000_0000_0000_0000_0000_0000_0000_0001);
168174522d2cSopenharmony_ci        assert_eq!(Flags128::B.bits, 0x0000_0000_0000_1000_0000_0000_0000_0000);
168274522d2cSopenharmony_ci        assert_eq!(Flags128::C.bits, 0x8000_0000_0000_0000_0000_0000_0000_0000);
168374522d2cSopenharmony_ci        assert_eq!(
168474522d2cSopenharmony_ci            Flags128::ABC.bits,
168574522d2cSopenharmony_ci            0x8000_0000_0000_1000_0000_0000_0000_0001
168674522d2cSopenharmony_ci        );
168774522d2cSopenharmony_ci        assert_eq!(format!("{:?}", Flags128::A), "A");
168874522d2cSopenharmony_ci        assert_eq!(format!("{:?}", Flags128::B), "B");
168974522d2cSopenharmony_ci        assert_eq!(format!("{:?}", Flags128::C), "C");
169074522d2cSopenharmony_ci        assert_eq!(format!("{:?}", Flags128::ABC), "A | B | C | ABC");
169174522d2cSopenharmony_ci    }
169274522d2cSopenharmony_ci
169374522d2cSopenharmony_ci    #[test]
169474522d2cSopenharmony_ci    fn test_serde_bitflags_serialize() {
169574522d2cSopenharmony_ci        let flags = SerdeFlags::A | SerdeFlags::B;
169674522d2cSopenharmony_ci
169774522d2cSopenharmony_ci        let serialized = serde_json::to_string(&flags).unwrap();
169874522d2cSopenharmony_ci
169974522d2cSopenharmony_ci        assert_eq!(serialized, r#"{"bits":3}"#);
170074522d2cSopenharmony_ci    }
170174522d2cSopenharmony_ci
170274522d2cSopenharmony_ci    #[test]
170374522d2cSopenharmony_ci    fn test_serde_bitflags_deserialize() {
170474522d2cSopenharmony_ci        let deserialized: SerdeFlags = serde_json::from_str(r#"{"bits":12}"#).unwrap();
170574522d2cSopenharmony_ci
170674522d2cSopenharmony_ci        let expected = SerdeFlags::C | SerdeFlags::D;
170774522d2cSopenharmony_ci
170874522d2cSopenharmony_ci        assert_eq!(deserialized.bits, expected.bits);
170974522d2cSopenharmony_ci    }
171074522d2cSopenharmony_ci
171174522d2cSopenharmony_ci    #[test]
171274522d2cSopenharmony_ci    fn test_serde_bitflags_roundtrip() {
171374522d2cSopenharmony_ci        let flags = SerdeFlags::A | SerdeFlags::B;
171474522d2cSopenharmony_ci
171574522d2cSopenharmony_ci        let deserialized: SerdeFlags = serde_json::from_str(&serde_json::to_string(&flags).unwrap()).unwrap();
171674522d2cSopenharmony_ci
171774522d2cSopenharmony_ci        assert_eq!(deserialized.bits, flags.bits);
171874522d2cSopenharmony_ci    }
171974522d2cSopenharmony_ci
172074522d2cSopenharmony_ci    bitflags! {
172174522d2cSopenharmony_ci        #[derive(serde::Serialize, serde::Deserialize)]
172274522d2cSopenharmony_ci        struct SerdeFlags: u32 {
172374522d2cSopenharmony_ci            const A = 1;
172474522d2cSopenharmony_ci            const B = 2;
172574522d2cSopenharmony_ci            const C = 4;
172674522d2cSopenharmony_ci            const D = 8;
172774522d2cSopenharmony_ci        }
172874522d2cSopenharmony_ci    }
172974522d2cSopenharmony_ci}
1730