enumflags2/
lib.rs

1//! # Enum Flags
2//! `enumflags2` implements the classic bitflags datastructure. Annotate an enum
3//! with `#[bitflags]`, and `BitFlags<YourEnum>` will be able to hold arbitrary combinations
4//! of your enum within the space of a single integer.
5//!
6//! ## Example
7//! ```
8//! use enumflags2::{bitflags, make_bitflags, BitFlags};
9//!
10//! #[bitflags]
11//! #[repr(u8)]
12//! #[derive(Copy, Clone, Debug, PartialEq)]
13//! enum Test {
14//!     A = 0b0001,
15//!     B = 0b0010,
16//!     C, // unspecified variants pick unused bits automatically
17//!     D = 0b1000,
18//! }
19//!
20//! // Flags can be combined with |, this creates a BitFlags of your type:
21//! let a_b: BitFlags<Test> = Test::A | Test::B;
22//! let a_c = Test::A | Test::C;
23//! let b_c_d = make_bitflags!(Test::{B | C | D});
24//!
25//! // The debug output lets you inspect both the numeric value and
26//! // the actual flags:
27//! assert_eq!(format!("{:?}", a_b), "BitFlags<Test>(0b11, A | B)");
28//!
29//! // But if you'd rather see only one of those, that's available too:
30//! assert_eq!(format!("{}", a_b), "A | B");
31//! assert_eq!(format!("{:04b}", a_b), "0011");
32//!
33//! // Iterate over the flags like a normal set
34//! assert_eq!(a_b.iter().collect::<Vec<_>>(), &[Test::A, Test::B]);
35//!
36//! // Query the contents with contains and intersects
37//! assert!(a_b.contains(Test::A));
38//! assert!(b_c_d.contains(Test::B | Test::C));
39//! assert!(!(b_c_d.contains(a_b)));
40//!
41//! assert!(a_b.intersects(a_c));
42//! assert!(!(a_b.intersects(Test::C | Test::D)));
43//! ```
44//!
45//! ## Optional Feature Flags
46//!
47//! - [`serde`](https://serde.rs/) implements `Serialize` and `Deserialize`
48//!   for `BitFlags<T>`.
49//! - `std` implements `std::error::Error` for `FromBitsError`.
50//!
51//! ## `const fn`-compatible APIs
52//!
53//! **Background:** The subset of `const fn` features currently stabilized is pretty limited.
54//! Most notably, [const traits are still at the RFC stage][const-trait-rfc],
55//! which makes it impossible to use any overloaded operators in a const
56//! context.
57//!
58//! **Naming convention:** If a separate, more limited function is provided
59//! for usage in a `const fn`, the name is suffixed with `_c`.
60//!
61//! **Blanket implementations:** If you attempt to write a `const fn` ranging
62//! over `T: BitFlag`, you will be met with an error explaining that currently,
63//! the only allowed trait bound for a `const fn` is `?Sized`. You will probably
64//! want to write a separate implementation for `BitFlags<T, u8>`,
65//! `BitFlags<T, u16>`, etc — best accomplished by a simple macro.
66//!
67//! **Documentation considerations:** The strategy described above is often used
68//! by `enumflags2` itself. To avoid clutter in the auto-generated documentation,
69//! the implementations for widths other than `u8` are marked with `#[doc(hidden)]`.
70//!
71//! ## Customizing `Default`
72//!
73//! By default, creating an instance of `BitFlags<T>` with `Default` will result in an empty
74//! set. If that's undesirable, you may customize this:
75//!
76//! ```
77//! # use enumflags2::{BitFlags, bitflags};
78//! #[bitflags(default = B | C)]
79//! #[repr(u8)]
80//! #[derive(Copy, Clone, Debug, PartialEq)]
81//! enum Test {
82//!     A = 0b0001,
83//!     B = 0b0010,
84//!     C = 0b0100,
85//!     D = 0b1000,
86//! }
87//!
88//! assert_eq!(BitFlags::default(), Test::B | Test::C);
89//! ```
90//!
91//! [const-trait-rfc]: https://github.com/rust-lang/rfcs/pull/2632
92#![warn(missing_docs)]
93#![cfg_attr(all(not(test), not(feature = "std")), no_std)]
94
95use core::hash::{Hash, Hasher};
96use core::marker::PhantomData;
97use core::{cmp, ops};
98
99#[allow(unused_imports)]
100#[macro_use]
101extern crate enumflags2_derive;
102
103#[doc(hidden)]
104pub use enumflags2_derive::bitflags_internal as bitflags;
105
106// Internal macro: expand into a separate copy for each supported numeric type.
107macro_rules! for_each_uint {
108    ( $d:tt $tyvar:ident $dd:tt $docattr:ident => $($input:tt)* ) => {
109        macro_rules! implement {
110            ( $d $tyvar:ty => $d($d $docattr:meta)? ) => {
111                $($input)*
112            }
113        }
114
115        implement! { u8 => }
116        implement! { u16 => doc(hidden) }
117        implement! { u32 => doc(hidden) }
118        implement! { u64 => doc(hidden) }
119        implement! { u128 => doc(hidden) }
120    }
121}
122
123/// A trait automatically implemented by `#[bitflags]` to make the enum
124/// a valid type parameter for `BitFlags<T>`.
125pub trait BitFlag: Copy + Clone + 'static + _internal::RawBitFlags {
126    /// Create a `BitFlags` with no flags set (in other words, with a value of 0).
127    ///
128    /// This is a convenience reexport of [`BitFlags::empty`]. It can be called with
129    /// `MyFlag::empty()`, thus bypassing the need for type hints in some situations.
130    ///
131    /// ```
132    /// # use enumflags2::{bitflags, BitFlags};
133    /// #[bitflags]
134    /// #[repr(u8)]
135    /// #[derive(Clone, Copy, PartialEq, Eq)]
136    /// enum MyFlag {
137    ///     One = 1 << 0,
138    ///     Two = 1 << 1,
139    ///     Three = 1 << 2,
140    /// }
141    ///
142    /// use enumflags2::BitFlag;
143    ///
144    /// let empty = MyFlag::empty();
145    /// assert!(empty.is_empty());
146    /// assert_eq!(empty.contains(MyFlag::One), false);
147    /// assert_eq!(empty.contains(MyFlag::Two), false);
148    /// assert_eq!(empty.contains(MyFlag::Three), false);
149    /// ```
150    #[inline]
151    fn empty() -> BitFlags<Self> {
152        BitFlags::empty()
153    }
154
155    /// Create a `BitFlags` with all flags set.
156    ///
157    /// This is a convenience reexport of [`BitFlags::all`]. It can be called with
158    /// `MyFlag::all()`, thus bypassing the need for type hints in some situations.
159    ///
160    /// ```
161    /// # use enumflags2::{bitflags, BitFlags};
162    /// #[bitflags]
163    /// #[repr(u8)]
164    /// #[derive(Clone, Copy, PartialEq, Eq)]
165    /// enum MyFlag {
166    ///     One = 1 << 0,
167    ///     Two = 1 << 1,
168    ///     Three = 1 << 2,
169    /// }
170    ///
171    /// use enumflags2::BitFlag;
172    ///
173    /// let all = MyFlag::all();
174    /// assert!(all.is_all());
175    /// assert_eq!(all.contains(MyFlag::One), true);
176    /// assert_eq!(all.contains(MyFlag::Two), true);
177    /// assert_eq!(all.contains(MyFlag::Three), true);
178    /// ```
179    #[inline]
180    fn all() -> BitFlags<Self> {
181        BitFlags::all()
182    }
183
184    /// Create a `BitFlags` if the raw value provided does not contain
185    /// any illegal flags.
186    ///
187    /// This is a convenience reexport of [`BitFlags::from_bits`]. It can be called
188    /// with `MyFlag::from_bits(bits)`, thus bypassing the need for type hints in
189    /// some situations.
190    ///
191    /// ```
192    /// # use enumflags2::{bitflags, BitFlags};
193    /// #[bitflags]
194    /// #[repr(u8)]
195    /// #[derive(Clone, Copy, PartialEq, Eq, Debug)]
196    /// enum MyFlag {
197    ///     One = 1 << 0,
198    ///     Two = 1 << 1,
199    ///     Three = 1 << 2,
200    /// }
201    ///
202    /// use enumflags2::BitFlag;
203    ///
204    /// let flags = MyFlag::from_bits(0b11).unwrap();
205    /// assert_eq!(flags.contains(MyFlag::One), true);
206    /// assert_eq!(flags.contains(MyFlag::Two), true);
207    /// assert_eq!(flags.contains(MyFlag::Three), false);
208    /// let invalid = MyFlag::from_bits(1 << 3);
209    /// assert!(invalid.is_err());
210    /// ```
211    #[inline]
212    fn from_bits(bits: Self::Numeric) -> Result<BitFlags<Self>, FromBitsError<Self>> {
213        BitFlags::from_bits(bits)
214    }
215
216    /// Create a `BitFlags` from an underlying bitwise value. If any
217    /// invalid bits are set, ignore them.
218    ///
219    /// This is a convenience reexport of [`BitFlags::from_bits_truncate`]. It can be
220    /// called with `MyFlag::from_bits_truncate(bits)`, thus bypassing the need for
221    /// type hints in some situations.
222    ///
223    /// ```
224    /// # use enumflags2::{bitflags, BitFlags};
225    /// #[bitflags]
226    /// #[repr(u8)]
227    /// #[derive(Clone, Copy, PartialEq, Eq)]
228    /// enum MyFlag {
229    ///     One = 1 << 0,
230    ///     Two = 1 << 1,
231    ///     Three = 1 << 2,
232    /// }
233    ///
234    /// use enumflags2::BitFlag;
235    ///
236    /// let flags = MyFlag::from_bits_truncate(0b1_1011);
237    /// assert_eq!(flags.contains(MyFlag::One), true);
238    /// assert_eq!(flags.contains(MyFlag::Two), true);
239    /// assert_eq!(flags.contains(MyFlag::Three), false);
240    /// ```
241    #[inline]
242    fn from_bits_truncate(bits: Self::Numeric) -> BitFlags<Self> {
243        BitFlags::from_bits_truncate(bits)
244    }
245
246    /// Create a `BitFlags` unsafely, without checking if the bits form
247    /// a valid bit pattern for the type.
248    ///
249    /// Consider using [`from_bits`][BitFlag::from_bits]
250    /// or [`from_bits_truncate`][BitFlag::from_bits_truncate] instead.
251    ///
252    /// # Safety
253    ///
254    /// All bits set in `val` must correspond to a value of the enum.
255    ///
256    /// # Example 
257    ///
258    /// This is a convenience reexport of [`BitFlags::from_bits_unchecked`]. It can be
259    /// called with `MyFlag::from_bits_unchecked(bits)`, thus bypassing the need for
260    /// type hints in some situations.
261    ///
262    /// ```
263    /// # use enumflags2::{bitflags, BitFlags};
264    /// #[bitflags]
265    /// #[repr(u8)]
266    /// #[derive(Clone, Copy, PartialEq, Eq)]
267    /// enum MyFlag {
268    ///     One = 1 << 0,
269    ///     Two = 1 << 1,
270    ///     Three = 1 << 2,
271    /// }
272    ///
273    /// use enumflags2::BitFlag;
274    ///
275    /// let flags = unsafe {
276    ///     MyFlag::from_bits_unchecked(0b011)
277    /// };
278    ///
279    /// assert_eq!(flags.contains(MyFlag::One), true);
280    /// assert_eq!(flags.contains(MyFlag::Two), true);
281    /// assert_eq!(flags.contains(MyFlag::Three), false);
282    /// ```
283    #[inline]
284    unsafe fn from_bits_unchecked(bits: Self::Numeric) -> BitFlags<Self> {
285        BitFlags::from_bits_unchecked(bits)
286    }
287}
288
289/// While the module is public, this is only the case because it needs to be
290/// accessed by the macro. Do not use this directly. Stability guarantees
291/// don't apply.
292#[doc(hidden)]
293pub mod _internal {
294    /// A trait automatically implemented by `#[bitflags]` to make the enum
295    /// a valid type parameter for `BitFlags<T>`.
296    ///
297    /// # Safety
298    ///
299    /// The values should reflect reality, like they do if the implementation
300    /// is generated by the procmacro.
301    pub unsafe trait RawBitFlags: Copy + Clone + 'static {
302        /// The underlying integer type.
303        type Numeric: BitFlagNum;
304
305        /// A value with no bits set.
306        const EMPTY: Self::Numeric;
307
308        /// The value used by the Default implementation. Equivalent to EMPTY, unless
309        /// customized.
310        const DEFAULT: Self::Numeric;
311
312        /// A value with all flag bits set.
313        const ALL_BITS: Self::Numeric;
314
315        /// The name of the type for debug formatting purposes.
316        ///
317        /// This is typically `BitFlags<EnumName>`
318        const BITFLAGS_TYPE_NAME: &'static str;
319
320        /// Return the bits as a number type.
321        fn bits(self) -> Self::Numeric;
322    }
323
324    use ::core::cmp::PartialOrd;
325    use ::core::fmt;
326    use ::core::ops::{BitAnd, BitOr, BitXor, Not, Sub};
327    use ::core::hash::Hash;
328
329    pub trait BitFlagNum:
330        Default
331        + BitOr<Self, Output = Self>
332        + BitAnd<Self, Output = Self>
333        + BitXor<Self, Output = Self>
334        + Sub<Self, Output = Self>
335        + Not<Output = Self>
336        + PartialOrd<Self>
337        + Ord
338        + Hash
339        + fmt::Debug
340        + fmt::Binary
341        + Copy
342        + Clone
343    {
344        const ONE: Self;
345
346        fn is_power_of_two(self) -> bool;
347        fn count_ones(self) -> u32;
348        fn wrapping_neg(self) -> Self;
349    }
350
351    for_each_uint! { $ty $hide_docs =>
352        impl BitFlagNum for $ty {
353            const ONE: Self = 1;
354
355            fn is_power_of_two(self) -> bool {
356                <$ty>::is_power_of_two(self)
357            }
358
359            fn count_ones(self) -> u32 {
360                <$ty>::count_ones(self)
361            }
362
363            fn wrapping_neg(self) -> Self {
364                <$ty>::wrapping_neg(self)
365            }
366        }
367    }
368
369    // Re-export libcore so the macro doesn't inject "extern crate" downstream.
370    pub mod core {
371        pub use core::{convert, ops, option};
372    }
373
374    pub struct AssertionSucceeded;
375    pub struct AssertionFailed;
376    pub trait ExactlyOneBitSet {
377        type X;
378    }
379    impl ExactlyOneBitSet for AssertionSucceeded {
380        type X = ();
381    }
382
383    pub trait AssertionHelper {
384        type Status;
385    }
386
387    impl AssertionHelper for [(); 1] {
388        type Status = AssertionSucceeded;
389    }
390
391    impl AssertionHelper for [(); 0] {
392        type Status = AssertionFailed;
393    }
394
395    pub const fn next_bit(x: u128) -> u128 {
396        1 << x.trailing_ones()
397    }
398}
399
400use _internal::BitFlagNum;
401
402// Internal debug formatting implementations
403mod formatting;
404
405// impl TryFrom<T::Numeric> for BitFlags<T>
406mod fallible;
407pub use crate::fallible::FromBitsError;
408
409mod iter;
410pub use crate::iter::Iter;
411
412mod const_api;
413pub use crate::const_api::ConstToken;
414
415/// Represents a set of flags of some type `T`.
416/// `T` must have the `#[bitflags]` attribute applied.
417///
418/// A `BitFlags<T>` is as large as the `T` itself,
419/// and stores one flag per bit.
420///
421/// ## Comparison operators, [`PartialOrd`] and [`Ord`]
422///
423/// To make it possible to use `BitFlags` as the key of a
424/// [`BTreeMap`][std::collections::BTreeMap], `BitFlags` implements
425/// [`Ord`]. There is no meaningful total order for bitflags,
426/// so the implementation simply compares the integer values of the bits.
427///
428/// Unfortunately, this means that comparing `BitFlags` with an operator
429/// like `<=` will compile, and return values that are probably useless
430/// and not what you expect. In particular, `<=` does *not* check whether
431/// one value is a subset of the other. Use [`BitFlags::contains`] for that.
432///
433/// ## Customizing `Default`
434///
435/// By default, creating an instance of `BitFlags<T>` with `Default` will result
436/// in an empty set. If that's undesirable, you may customize this:
437///
438/// ```
439/// # use enumflags2::{BitFlags, bitflags};
440/// #[bitflags(default = B | C)]
441/// #[repr(u8)]
442/// #[derive(Copy, Clone, Debug, PartialEq)]
443/// enum MyFlag {
444///     A = 0b0001,
445///     B = 0b0010,
446///     C = 0b0100,
447///     D = 0b1000,
448/// }
449///
450/// assert_eq!(BitFlags::default(), MyFlag::B | MyFlag::C);
451/// ```
452///
453/// ## Memory layout
454///
455/// `BitFlags<T>` is marked with the `#[repr(transparent)]` trait, meaning
456/// it can be safely transmuted into the corresponding numeric type.
457///
458/// Usually, the same can be achieved by using [`BitFlags::bits`] in one
459/// direction, and [`BitFlags::from_bits`], [`BitFlags::from_bits_truncate`],
460/// or [`BitFlags::from_bits_unchecked`] in the other direction. However,
461/// transmuting might still be useful if, for example, you're dealing with
462/// an entire array of `BitFlags`.
463///
464/// When transmuting *into* a `BitFlags`, make sure that each set bit
465/// corresponds to an existing flag
466/// (cf. [`from_bits_unchecked`][BitFlags::from_bits_unchecked]).
467///
468/// For example:
469///
470/// ```
471/// # use enumflags2::{BitFlags, bitflags};
472/// #[bitflags]
473/// #[repr(u8)] // <-- the repr determines the numeric type
474/// #[derive(Copy, Clone)]
475/// enum TransmuteMe {
476///     One = 1 << 0,
477///     Two = 1 << 1,
478/// }
479///
480/// # use std::slice;
481/// // NOTE: we use a small, self-contained function to handle the slice
482/// // conversion to make sure the lifetimes are right.
483/// fn transmute_slice<'a>(input: &'a [BitFlags<TransmuteMe>]) -> &'a [u8] {
484///     unsafe {
485///         slice::from_raw_parts(input.as_ptr() as *const u8, input.len())
486///     }
487/// }
488///
489/// let many_flags = &[
490///     TransmuteMe::One.into(),
491///     TransmuteMe::One | TransmuteMe::Two,
492/// ];
493///
494/// let as_nums = transmute_slice(many_flags);
495/// assert_eq!(as_nums, &[0b01, 0b11]);
496/// ```
497///
498/// ## Implementation notes
499///
500/// You might expect this struct to be defined as
501///
502/// ```ignore
503/// struct BitFlags<T: BitFlag> {
504///     value: T::Numeric
505/// }
506/// ```
507///
508/// Ideally, that would be the case. However, because `const fn`s cannot
509/// have trait bounds in current Rust, this would prevent us from providing
510/// most `const fn` APIs. As a workaround, we define `BitFlags` with two
511/// type parameters, with a default for the second one:
512///
513/// ```ignore
514/// struct BitFlags<T, N = <T as BitFlag>::Numeric> {
515///     value: N,
516///     marker: PhantomData<T>,
517/// }
518/// ```
519///
520/// Manually providing a type for the `N` type parameter shouldn't ever
521/// be necessary.
522///
523/// The types substituted for `T` and `N` must always match, creating a
524/// `BitFlags` value where that isn't the case is only possible with
525/// incorrect unsafe code.
526#[derive(Copy, Clone)]
527#[repr(transparent)]
528pub struct BitFlags<T, N = <T as _internal::RawBitFlags>::Numeric> {
529    val: N,
530    marker: PhantomData<T>,
531}
532
533/// `make_bitflags!` provides a succint syntax for creating instances of
534/// `BitFlags<T>`. Instead of repeating the name of your type for each flag
535/// you want to add, try `make_bitflags!(Flags::{Foo | Bar})`.
536/// ```
537/// use enumflags2::{bitflags, make_bitflags};
538/// #[bitflags]
539/// #[repr(u8)]
540/// #[derive(Clone, Copy, Debug)]
541/// enum Test {
542///     A = 1 << 0,
543///     B = 1 << 1,
544///     C = 1 << 2,
545/// }
546/// let x = make_bitflags!(Test::{A | C});
547/// assert_eq!(x, Test::A | Test::C);
548/// ```
549#[macro_export]
550macro_rules! make_bitflags {
551    ( $enum:ident ::{ $($variant:ident)|* } ) => {
552        {
553            let mut n = 0;
554            $(
555                {
556                    let flag: $enum = $enum::$variant;
557                    n |= flag as <$enum as $crate::_internal::RawBitFlags>::Numeric;
558                }
559            )*
560            // SAFETY: The value has been created from numeric values of the underlying
561            // enum, so only valid bits are set.
562            unsafe { $crate::BitFlags::<$enum>::from_bits_unchecked_c(
563                    n, $crate::BitFlags::CONST_TOKEN) }
564        }
565    }
566}
567
568/// The default value returned is one with all flags unset, i. e. [`empty`][Self::empty],
569/// unless [customized](index.html#customizing-default).
570impl<T> Default for BitFlags<T>
571where
572    T: BitFlag,
573{
574    #[inline(always)]
575    fn default() -> Self {
576        BitFlags {
577            val: T::DEFAULT,
578            marker: PhantomData,
579        }
580    }
581}
582
583impl<T: BitFlag> From<T> for BitFlags<T> {
584    #[inline(always)]
585    fn from(t: T) -> BitFlags<T> {
586        Self::from_flag(t)
587    }
588}
589
590impl<T> BitFlags<T>
591where
592    T: BitFlag,
593{
594    /// Create a `BitFlags` if the raw value provided does not contain
595    /// any illegal flags.
596    ///
597    /// See also: [a convenience re-export in the `BitFlag` trait][BitFlag::from_bits],
598    /// which can help avoid the need for type hints.
599    ///
600    /// ```
601    /// # use enumflags2::{bitflags, BitFlags};
602    /// #[bitflags]
603    /// #[repr(u8)]
604    /// #[derive(Clone, Copy, PartialEq, Eq, Debug)]
605    /// enum MyFlag {
606    ///     One = 1 << 0,
607    ///     Two = 1 << 1,
608    ///     Three = 1 << 2,
609    /// }
610    ///
611    /// let flags: BitFlags<MyFlag> = BitFlags::from_bits(0b11).unwrap();
612    /// assert_eq!(flags.contains(MyFlag::One), true);
613    /// assert_eq!(flags.contains(MyFlag::Two), true);
614    /// assert_eq!(flags.contains(MyFlag::Three), false);
615    /// let invalid = BitFlags::<MyFlag>::from_bits(1 << 3);
616    /// assert!(invalid.is_err());
617    /// ```
618    #[inline]
619    pub fn from_bits(bits: T::Numeric) -> Result<Self, FromBitsError<T>> {
620        let flags = Self::from_bits_truncate(bits);
621        if flags.bits() == bits {
622            Ok(flags)
623        } else {
624            Err(FromBitsError {
625                flags,
626                invalid: bits & !flags.bits(),
627            })
628        }
629    }
630
631    /// Create a `BitFlags` from an underlying bitwise value. If any
632    /// invalid bits are set, ignore them.
633    ///
634    /// See also: [a convenience re-export in the `BitFlag` trait][BitFlag::from_bits_truncate],
635    /// which can help avoid the need for type hints.
636    ///
637    /// ```
638    /// # use enumflags2::{bitflags, BitFlags};
639    /// #[bitflags]
640    /// #[repr(u8)]
641    /// #[derive(Clone, Copy, PartialEq, Eq)]
642    /// enum MyFlag {
643    ///     One = 1 << 0,
644    ///     Two = 1 << 1,
645    ///     Three = 1 << 2,
646    /// }
647    ///
648    /// let flags: BitFlags<MyFlag> = BitFlags::from_bits_truncate(0b1_1011);
649    /// assert_eq!(flags.contains(MyFlag::One), true);
650    /// assert_eq!(flags.contains(MyFlag::Two), true);
651    /// assert_eq!(flags.contains(MyFlag::Three), false);
652    /// ```
653    #[must_use]
654    #[inline(always)]
655    pub fn from_bits_truncate(bits: T::Numeric) -> Self {
656        // SAFETY: We're truncating out all the invalid bits, so the remaining
657        // ones must be valid.
658        unsafe { BitFlags::from_bits_unchecked(bits & T::ALL_BITS) }
659    }
660
661    /// Create a new BitFlags unsafely, without checking if the bits form
662    /// a valid bit pattern for the type.
663    ///
664    /// Consider using [`from_bits`][BitFlags::from_bits]
665    /// or [`from_bits_truncate`][BitFlags::from_bits_truncate] instead.
666    ///
667    /// # Safety
668    ///
669    /// All bits set in `val` must correspond to a value of the enum.
670    ///
671    /// # Example
672    ///
673    /// ```
674    /// # use enumflags2::{bitflags, BitFlags};
675    /// #[bitflags]
676    /// #[repr(u8)]
677    /// #[derive(Clone, Copy, PartialEq, Eq)]
678    /// enum MyFlag {
679    ///     One = 1 << 0,
680    ///     Two = 1 << 1,
681    ///     Three = 1 << 2,
682    /// }
683    ///
684    /// let flags: BitFlags<MyFlag> = unsafe {
685    ///     BitFlags::from_bits_unchecked(0b011)
686    /// };
687    ///
688    /// assert_eq!(flags.contains(MyFlag::One), true);
689    /// assert_eq!(flags.contains(MyFlag::Two), true);
690    /// assert_eq!(flags.contains(MyFlag::Three), false);
691    /// ```
692    #[must_use]
693    #[inline(always)]
694    pub unsafe fn from_bits_unchecked(val: T::Numeric) -> Self {
695        BitFlags {
696            val,
697            marker: PhantomData,
698        }
699    }
700
701    /// Turn a `T` into a `BitFlags<T>`. Also available as `flag.into()`.
702    #[must_use]
703    #[inline(always)]
704    pub fn from_flag(flag: T) -> Self {
705        // SAFETY: A value of the underlying enum is valid by definition.
706        unsafe { Self::from_bits_unchecked(flag.bits()) }
707    }
708
709    /// Create a `BitFlags` with no flags set (in other words, with a value of `0`).
710    ///
711    /// See also: [`BitFlag::empty`], a convenience reexport;
712    /// [`BitFlags::EMPTY`], the same functionality available
713    /// as a constant for `const fn` code.
714    ///
715    /// ```
716    /// # use enumflags2::{bitflags, BitFlags};
717    /// #[bitflags]
718    /// #[repr(u8)]
719    /// #[derive(Clone, Copy, PartialEq, Eq)]
720    /// enum MyFlag {
721    ///     One = 1 << 0,
722    ///     Two = 1 << 1,
723    ///     Three = 1 << 2,
724    /// }
725    ///
726    /// let empty: BitFlags<MyFlag> = BitFlags::empty();
727    /// assert!(empty.is_empty());
728    /// assert_eq!(empty.contains(MyFlag::One), false);
729    /// assert_eq!(empty.contains(MyFlag::Two), false);
730    /// assert_eq!(empty.contains(MyFlag::Three), false);
731    /// ```
732    #[inline(always)]
733    pub fn empty() -> Self {
734        Self::EMPTY
735    }
736
737    /// Create a `BitFlags` with all flags set.
738    ///
739    /// See also: [`BitFlag::all`], a convenience reexport;
740    /// [`BitFlags::ALL`], the same functionality available
741    /// as a constant for `const fn` code.
742    ///
743    /// ```
744    /// # use enumflags2::{bitflags, BitFlags};
745    /// #[bitflags]
746    /// #[repr(u8)]
747    /// #[derive(Clone, Copy, PartialEq, Eq)]
748    /// enum MyFlag {
749    ///     One = 1 << 0,
750    ///     Two = 1 << 1,
751    ///     Three = 1 << 2,
752    /// }
753    ///
754    /// let empty: BitFlags<MyFlag> = BitFlags::all();
755    /// assert!(empty.is_all());
756    /// assert_eq!(empty.contains(MyFlag::One), true);
757    /// assert_eq!(empty.contains(MyFlag::Two), true);
758    /// assert_eq!(empty.contains(MyFlag::Three), true);
759    /// ```
760    #[inline(always)]
761    pub fn all() -> Self {
762        Self::ALL
763    }
764
765    /// Returns true if all flags are set
766    #[inline(always)]
767    pub fn is_all(self) -> bool {
768        self.val == T::ALL_BITS
769    }
770
771    /// Returns true if no flag is set
772    #[inline(always)]
773    pub fn is_empty(self) -> bool {
774        self.val == T::EMPTY
775    }
776
777    /// Returns the number of flags set.
778    #[inline(always)]
779    pub fn len(self) -> usize {
780        self.val.count_ones() as usize
781    }
782
783    /// If exactly one flag is set, the flag is returned. Otherwise, returns `None`.
784    ///
785    /// See also [`Itertools::exactly_one`](https://docs.rs/itertools/latest/itertools/trait.Itertools.html#method.exactly_one).
786    #[inline(always)]
787    pub fn exactly_one(self) -> Option<T> {
788        if self.val.is_power_of_two() {
789            // SAFETY: By the invariant of the BitFlags type, all bits are valid
790            // in isolation for the underlying enum.
791            Some(unsafe { core::mem::transmute_copy(&self.val) })
792        } else {
793            None
794        }
795    }
796
797    /// Returns the underlying bitwise value.
798    ///
799    /// ```
800    /// # use enumflags2::{bitflags, BitFlags};
801    /// #[bitflags]
802    /// #[repr(u8)]
803    /// #[derive(Clone, Copy)]
804    /// enum Flags {
805    ///     Foo = 1 << 0,
806    ///     Bar = 1 << 1,
807    /// }
808    ///
809    /// let both_flags = Flags::Foo | Flags::Bar;
810    /// assert_eq!(both_flags.bits(), 0b11);
811    /// ```
812    #[inline(always)]
813    pub fn bits(self) -> T::Numeric {
814        self.val
815    }
816
817    /// Returns true if at least one flag is shared.
818    #[inline(always)]
819    pub fn intersects<B: Into<BitFlags<T>>>(self, other: B) -> bool {
820        (self.bits() & other.into().bits()) != Self::EMPTY.val
821    }
822
823    /// Returns true if all flags are contained.
824    #[inline(always)]
825    pub fn contains<B: Into<BitFlags<T>>>(self, other: B) -> bool {
826        let other = other.into();
827        (self.bits() & other.bits()) == other.bits()
828    }
829
830    /// Toggles the matching bits
831    #[inline(always)]
832    pub fn toggle<B: Into<BitFlags<T>>>(&mut self, other: B) {
833        *self ^= other.into();
834    }
835
836    /// Inserts the flags into the BitFlag
837    #[inline(always)]
838    pub fn insert<B: Into<BitFlags<T>>>(&mut self, other: B) {
839        *self |= other.into();
840    }
841
842    /// Removes the matching flags
843    #[inline(always)]
844    pub fn remove<B: Into<BitFlags<T>>>(&mut self, other: B) {
845        *self &= !other.into();
846    }
847
848    /// Inserts if `cond` holds, else removes
849    ///
850    /// ```
851    /// # use enumflags2::bitflags;
852    /// #[bitflags]
853    /// #[derive(Clone, Copy, PartialEq, Debug)]
854    /// #[repr(u8)]
855    /// enum MyFlag {
856    ///     A = 1 << 0,
857    ///     B = 1 << 1,
858    ///     C = 1 << 2,
859    /// }
860    ///
861    /// let mut state = MyFlag::A | MyFlag::C;
862    /// state.set(MyFlag::A | MyFlag::B, false);
863    ///
864    /// // Because the condition was false, both
865    /// // `A` and `B` are removed from the set
866    /// assert_eq!(state, MyFlag::C);
867    /// ```
868    #[inline(always)]
869    pub fn set<B: Into<BitFlags<T>>>(&mut self, other: B, cond: bool) {
870        if cond {
871            self.insert(other);
872        } else {
873            self.remove(other);
874        }
875    }
876}
877
878impl<T, N: PartialEq> PartialEq for BitFlags<T, N> {
879    #[inline(always)]
880    fn eq(&self, other: &Self) -> bool {
881        self.val == other.val
882    }
883}
884
885impl<T, N: Eq> Eq for BitFlags<T, N> {}
886
887impl<T, N: PartialOrd> PartialOrd for BitFlags<T, N> {
888    #[inline(always)]
889    fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
890        self.val.partial_cmp(&other.val)
891    }
892}
893
894impl<T, N: Ord> Ord for BitFlags<T, N> {
895    #[inline(always)]
896    fn cmp(&self, other: &Self) -> cmp::Ordering {
897        self.val.cmp(&other.val)
898    }
899}
900
901// Clippy complains when Hash is derived while PartialEq is implemented manually
902impl<T, N: Hash> Hash for BitFlags<T, N> {
903    #[inline(always)]
904    fn hash<H: Hasher>(&self, state: &mut H) {
905        self.val.hash(state)
906    }
907}
908
909impl<T> cmp::PartialEq<T> for BitFlags<T>
910where
911    T: BitFlag,
912{
913    #[inline(always)]
914    fn eq(&self, other: &T) -> bool {
915        self.bits() == Into::<Self>::into(*other).bits()
916    }
917}
918
919impl<T, B> ops::BitOr<B> for BitFlags<T>
920where
921    T: BitFlag,
922    B: Into<BitFlags<T>>,
923{
924    type Output = BitFlags<T>;
925    #[inline(always)]
926    fn bitor(self, other: B) -> BitFlags<T> {
927        // SAFETY: The two operands are known to be composed of valid bits,
928        // and 0 | 0 = 0 in the columns of the invalid bits.
929        unsafe { BitFlags::from_bits_unchecked(self.bits() | other.into().bits()) }
930    }
931}
932
933impl<T, B> ops::BitAnd<B> for BitFlags<T>
934where
935    T: BitFlag,
936    B: Into<BitFlags<T>>,
937{
938    type Output = BitFlags<T>;
939    #[inline(always)]
940    fn bitand(self, other: B) -> BitFlags<T> {
941        // SAFETY: The two operands are known to be composed of valid bits,
942        // and 0 & 0 = 0 in the columns of the invalid bits.
943        unsafe { BitFlags::from_bits_unchecked(self.bits() & other.into().bits()) }
944    }
945}
946
947impl<T, B> ops::BitXor<B> for BitFlags<T>
948where
949    T: BitFlag,
950    B: Into<BitFlags<T>>,
951{
952    type Output = BitFlags<T>;
953    #[inline(always)]
954    fn bitxor(self, other: B) -> BitFlags<T> {
955        // SAFETY: The two operands are known to be composed of valid bits,
956        // and 0 ^ 0 = 0 in the columns of the invalid bits.
957        unsafe { BitFlags::from_bits_unchecked(self.bits() ^ other.into().bits()) }
958    }
959}
960
961impl<T, B> ops::BitOrAssign<B> for BitFlags<T>
962where
963    T: BitFlag,
964    B: Into<BitFlags<T>>,
965{
966    #[inline(always)]
967    fn bitor_assign(&mut self, other: B) {
968        *self = *self | other;
969    }
970}
971
972impl<T, B> ops::BitAndAssign<B> for BitFlags<T>
973where
974    T: BitFlag,
975    B: Into<BitFlags<T>>,
976{
977    #[inline(always)]
978    fn bitand_assign(&mut self, other: B) {
979        *self = *self & other;
980    }
981}
982impl<T, B> ops::BitXorAssign<B> for BitFlags<T>
983where
984    T: BitFlag,
985    B: Into<BitFlags<T>>,
986{
987    #[inline(always)]
988    fn bitxor_assign(&mut self, other: B) {
989        *self = *self ^ other;
990    }
991}
992
993impl<T> ops::Not for BitFlags<T>
994where
995    T: BitFlag,
996{
997    type Output = BitFlags<T>;
998    #[inline(always)]
999    fn not(self) -> BitFlags<T> {
1000        BitFlags::from_bits_truncate(!self.bits())
1001    }
1002}
1003
1004#[cfg(feature = "serde")]
1005mod impl_serde {
1006    use super::{BitFlag, BitFlags};
1007    use serde::de::{Error, Unexpected};
1008    use serde::{Deserialize, Serialize};
1009
1010    impl<'a, T> Deserialize<'a> for BitFlags<T>
1011    where
1012        T: BitFlag,
1013        T::Numeric: Deserialize<'a> + Into<u64>,
1014    {
1015        fn deserialize<D: serde::Deserializer<'a>>(d: D) -> Result<Self, D::Error> {
1016            let val = T::Numeric::deserialize(d)?;
1017            Self::from_bits(val).map_err(|_| {
1018                D::Error::invalid_value(
1019                    Unexpected::Unsigned(val.into()),
1020                    &"valid bit representation",
1021                )
1022            })
1023        }
1024    }
1025
1026    impl<T> Serialize for BitFlags<T>
1027    where
1028        T: BitFlag,
1029        T::Numeric: Serialize,
1030    {
1031        fn serialize<S: serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
1032            T::Numeric::serialize(&self.val, s)
1033        }
1034    }
1035}