Support generating enums as structs with associated consts
C++ enums are not like Rust C-like enums: they can have values other than the variants listed. This is often used to define bitflags types, like so:
enum SomeFlags {
NONE = 0,
FIRST = 1,
SECOND = 2,
THIRD = 4,
ALL = 7,
};
With current generation, there is no way to pass FIRST | SECOND from Rust, because creating Rust enum with invalid discriminant value is insta-UB. To support this pattern, autocxx should be able to codegen this into something like:
#[repr(transparent)]
pub struct SomeFlags(pub c_int);
impl SomeFlags {
pub const NONE: Self = Self(0);
pub const FIRST: Self = Self(1);
pub const SECOND: Self = Self(2);
pub const THIRD: Self = Self(4);
pub const ALL: Self = Self(7);
}
// ideally also impl BitOr for SomeFlags
This could be implemented as an additional annotation like bitflags!(SomeFlags) or enum_as_struct!(SomeFlags) or maybe as a global option .generate_enums_to_structs() on the generator.
Generating C++ enums as Rust enums is generally footguny (getting an invalid value from C++ code produces insta-UB in Rust), so I think changing this globally is sensible.
I'd be happy to accept a PR to add more modes here. Whatever we do, it should map closely to the various enum modes exposed by bindgen.
Will a PR that just adds .default_enum_style() to autocxx_build::Builder be accepted? It would probably be better to have granularity here, but being able to restore the default to the one used in cxx will already be very helpful.
If not, where would be a better place to configure this default?
Will a PR that just adds .default_enum_style() to autocxx_build::Builder be accepted? It would probably be better to have granularity here, but being able to restore the default to the one used in cxx will already be very helpful.
Yes, I think so. No promises till I see it, but that seems reasonable to me.
(For future reference - for granularity I'd expect something like an enum_style!(<enum name>, style) directive, which provides information to bindgen callbacks like this, though I'm not sure that bindgen callback is exactly right).