Skip to content

Commit a29f6d6

Browse files
committed
const fn: union, intersect
1 parent d6320bd commit a29f6d6

File tree

5 files changed

+74
-1
lines changed

5 files changed

+74
-1
lines changed

src/lib.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -365,6 +365,36 @@ impl<T: BitFlag> From<T> for BitFlags<T> {
365365
}
366366
}
367367

368+
for_each_uint! { ty =>
369+
impl<T> BitFlags<T, $ty> {
370+
/// Bitwise OR — return value contains flag if either argument does.
371+
///
372+
/// Also available as `a | b`, but operator overloads are not usable
373+
/// in `const fn`s at the moment.
374+
#[must_use]
375+
#[inline(always)]
376+
pub const fn union(self, other: Self) -> Self {
377+
BitFlags {
378+
val: self.val | other.val,
379+
marker: PhantomData,
380+
}
381+
}
382+
383+
/// Bitwise AND — return value contains flag if both arguments do.
384+
///
385+
/// Also available as `a & b`, but operator overloads are not usable
386+
/// in `const fn`s at the moment.
387+
#[must_use]
388+
#[inline(always)]
389+
pub const fn intersection(self, other: Self) -> Self {
390+
BitFlags {
391+
val: self.val & other.val,
392+
marker: PhantomData,
393+
}
394+
}
395+
}
396+
}
397+
368398
impl<T> BitFlags<T>
369399
where
370400
T: BitFlag,

test_suite/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ features = ["derive"]
1313

1414
[dev-dependencies]
1515
trybuild = "1.0"
16+
glob = "0.3"
1617

1718
[[test]]
1819
name = "ui-tests"

test_suite/ui/must_use_warning.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
use enumflags2::{bitflags, BitFlags};
2+
3+
#[bitflags]
4+
#[repr(u8)]
5+
#[derive(Clone, Copy, Debug)]
6+
enum Flag {
7+
Foo = 1 << 0,
8+
Bar = 1 << 1,
9+
}
10+
11+
fn main() {
12+
let mut thing: BitFlags<Flag> = Flag::Foo.into();
13+
let _ = thing;
14+
// let's pretend the unused_mut warning doesn't trigger
15+
thing = Flag::Bar.into();
16+
thing.union(Flag::Foo.into());
17+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
warning: unused import: `BitFlags`
2+
--> $DIR/must_use_warning.rs:1:28
3+
|
4+
1 | use enumflags2::{bitflags, BitFlags};
5+
| ^^^^^^^^
6+
|
7+
= note: `#[warn(unused_imports)]` on by default
8+
9+
error[E0599]: no method named `union` found for enum `Flag` in the current scope
10+
--> $DIR/must_use_warning.rs:13:11
11+
|
12+
6 | enum Flag {
13+
| --------- method `union` not found for this
14+
...
15+
13 | thing.union(Flag::Bar.into());
16+
| ^^^^^ method not found in `Flag`

test_suite/ui_tests.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
1+
use glob::glob;
2+
use std::os::unix::ffi::OsStrExt;
3+
14
#[test]
25
fn ui() {
36
let t = trybuild::TestCases::new();
4-
t.compile_fail("ui/*.rs");
7+
for test in glob("ui/*.rs").unwrap() {
8+
let path = test.unwrap();
9+
match path.as_os_str().as_bytes() {
10+
b"ui/must_use_warning.rs" => t.pass(path),
11+
_ => t.compile_fail(path),
12+
}
13+
}
514
}

0 commit comments

Comments
 (0)