@@ -374,6 +374,13 @@ impl<T: BitFlag> From<T> for BitFlags<T> {
374374 }
375375}
376376
377+ /// Workaround for `const fn` limitations.
378+ ///
379+ /// Some `const fn`s in this crate will need an instance of this type
380+ /// for some type-level information usually provided by traits.
381+ /// For an example of usage, see [`not_c`][BitFlags::not_c]
382+ pub struct ConstToken < T , N > ( BitFlags < T , N > ) ;
383+
377384impl < T > BitFlags < T >
378385where
379386 T : BitFlag ,
@@ -394,7 +401,9 @@ where
394401
395402 /// Create a `BitFlags` with no flags set (in other words, with a value of `0`).
396403 ///
397- /// See also: [`BitFlag::empty`], a convenience reexport.
404+ /// See also: [`BitFlag::empty`], a convenience reexport;
405+ /// [`BitFlags::EMPTY`], the same functionality available
406+ /// as a constant for `const fn` code.
398407 ///
399408 /// ```
400409 /// # use enumflags2::{bitflags, BitFlags};
@@ -420,7 +429,9 @@ where
420429
421430 /// Create a `BitFlags` with all flags set.
422431 ///
423- /// See also: [`BitFlag::all`], a convenience reexport.
432+ /// See also: [`BitFlag::all`], a convenience reexport;
433+ /// [`BitFlags::ALL`], the same functionality available
434+ /// as a constant for `const fn` code.
424435 ///
425436 /// ```
426437 /// # use enumflags2::{bitflags, BitFlags};
@@ -452,6 +463,9 @@ where
452463 /// but works in a const context.
453464 pub const ALL : Self = BitFlags { val : T :: ALL_BITS , marker : PhantomData } ;
454465
466+ /// A [`ConstToken`] for this type of flag.
467+ pub const CONST_TOKEN : ConstToken < T , T :: Numeric > = ConstToken ( Self :: ALL ) ;
468+
455469 /// Returns true if all flags are set
456470 #[ inline( always) ]
457471 pub fn is_all ( self ) -> bool {
@@ -577,6 +591,36 @@ for_each_uint! { $ty $hide_docs =>
577591 }
578592 }
579593
594+ /// Bitwise NOT — return value contains flag if argument doesn't.
595+ ///
596+ /// Also available as `!a`, but operator overloads are not usable
597+ /// in `const fn`s at the moment.
598+ ///
599+ /// Moreover, due to `const fn` limitations, `not_c` needs a
600+ /// [`ConstToken`] as an argument.
601+ ///
602+ /// ```
603+ /// # use enumflags2::{bitflags, BitFlags};
604+ /// #[bitflags]
605+ /// #[repr(u8)]
606+ /// #[derive(Clone, Copy, Debug, PartialEq, Eq)]
607+ /// enum MyFlag {
608+ /// One = 1 << 0,
609+ /// Two = 1 << 1,
610+ /// Three = 1 << 2,
611+ /// }
612+ ///
613+ /// let flags = MyFlag::One | MyFlag::Two;
614+ /// let negated = flags.not_c(BitFlags::CONST_TOKEN);
615+ /// assert_eq!(negated, MyFlag::Three);
616+ /// ```
617+ pub const fn not_c( self , const_token: ConstToken <T , $ty>) -> Self {
618+ BitFlags {
619+ val: !self . val & const_token. 0 . val,
620+ marker: PhantomData ,
621+ }
622+ }
623+
580624 /// Returns the underlying bitwise value.
581625 ///
582626 /// `const` variant of [`bits`][BitFlags::bits].
0 commit comments