cxx icon indicating copy to clipboard operation
cxx copied to clipboard

Derive bitwise BitAnd and BitOr for shared enums

Open dtolnay opened this issue 4 years ago • 1 comments

C++ enums come with bit operators:

enum Enum {
  A = 1,
  B = 2,
  C = 4,
};

int main() {
  auto x = Enum::A | Enum::B;
}

We should provide a way to expose the same on the Rust side via derived impls of https://doc.rust-lang.org/std/ops/trait.BitAnd.html and https://doc.rust-lang.org/std/ops/trait.BitOr.html.

#[cxx::bridge]
mod ffi {
    #[derive(BitAnd, BitOr)]
    enum Enum {
        A = 1,
        B = 2,
        C = 4,
    }
}

dtolnay avatar Mar 17 '21 03:03 dtolnay

until it is implemented as part of the language itself (if ever), a bit of as magic does the job without any bitor/bitand trait implementation (makes the code a bit longer but it is very simple)

enum BITS {
    ONE = 0b0001,
    TWO = 0b0010,
    FOUR = 0b0100,
    EIGHT = 0b1000,
}

fn main() {
    let flags: u8;

    flags = BITS::ONE as u8 | BITS::FOUR as u8 | BITS::EIGHT as u8;

    println!("{flags:b}")
}

PS: you will get warning of this shape if you don't use all enums in the code: "warning: variant TWO is never constructed", but, again, it is just a warning that can be handled gracefully.

edit: changed i8 to u8 to use 8th bit PS: Do not confuse if you see this at SO as I have it at https://stackoverflow.com/a/76603396/9512475

yilmazdurmaz avatar Jul 03 '23 09:07 yilmazdurmaz