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