Skip to content

Commit cdf0adb

Browse files
committed
Implement not_c
1 parent 5e4b2f3 commit cdf0adb

File tree

1 file changed

+46
-2
lines changed

1 file changed

+46
-2
lines changed

src/lib.rs

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
377384
impl<T> BitFlags<T>
378385
where
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

Comments
 (0)