Skip to content

Commit

Permalink
bitflags: Make more operations constexpr.
Browse files Browse the repository at this point in the history
  • Loading branch information
emilio committed Jun 7, 2022
1 parent f0d4f28 commit 0ee47b3
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 27 deletions.
26 changes: 19 additions & 7 deletions src/bindgen/ir/structure.rs
Expand Up @@ -205,14 +205,16 @@ impl Struct {

fn emit_bitflags_binop<F: Write>(
&self,
constexpr_prefix: &str,
operator: char,
other: &str,
out: &mut SourceWriter<F>,
) {
out.new_line();
write!(
out,
"{} operator{}(const {}& {}) const",
"{}{} operator{}(const {}& {}) const",
constexpr_prefix,
self.export_name(),
operator,
self.export_name(),
Expand Down Expand Up @@ -531,21 +533,31 @@ impl Source for Struct {
wrote_start_newline = true;
out.new_line();
}
let constexpr_prefix = if config.constant.allow_constexpr {
"constexpr "
} else {
""
};

out.new_line();
write!(out, "explicit operator bool() const");
write!(out, "{}explicit operator bool() const", constexpr_prefix);
out.open_brace();
write!(out, "return !!bits;");
out.close_brace(false);

out.new_line();
write!(out, "{} operator~() const", self.export_name());
write!(
out,
"{}{} operator~() const",
constexpr_prefix,
self.export_name()
);
out.open_brace();
write!(out, "return {{static_cast<decltype(bits)>(~bits)}};");
out.close_brace(false);

self.emit_bitflags_binop('|', &other, out);
self.emit_bitflags_binop('&', &other, out);
self.emit_bitflags_binop('^', &other, out);
self.emit_bitflags_binop(constexpr_prefix, '|', &other, out);
self.emit_bitflags_binop(constexpr_prefix, '&', &other, out);
self.emit_bitflags_binop(constexpr_prefix, '^', &other, out);
}

// Generate a serializer function that allows dumping this struct
Expand Down
10 changes: 5 additions & 5 deletions tests/expectations/associated_in_body.cpp
Expand Up @@ -10,27 +10,27 @@
struct StyleAlignFlags {
uint8_t bits;

explicit operator bool() const {
constexpr explicit operator bool() const {
return !!bits;
}
StyleAlignFlags operator~() const {
constexpr StyleAlignFlags operator~() const {
return {static_cast<decltype(bits)>(~bits)};
}
StyleAlignFlags operator|(const StyleAlignFlags& other) const {
constexpr StyleAlignFlags operator|(const StyleAlignFlags& other) const {
return {static_cast<decltype(bits)>(this->bits | other.bits)};
}
StyleAlignFlags& operator|=(const StyleAlignFlags& other) {
*this = (*this | other);
return *this;
}
StyleAlignFlags operator&(const StyleAlignFlags& other) const {
constexpr StyleAlignFlags operator&(const StyleAlignFlags& other) const {
return {static_cast<decltype(bits)>(this->bits & other.bits)};
}
StyleAlignFlags& operator&=(const StyleAlignFlags& other) {
*this = (*this & other);
return *this;
}
StyleAlignFlags operator^(const StyleAlignFlags& other) const {
constexpr StyleAlignFlags operator^(const StyleAlignFlags& other) const {
return {static_cast<decltype(bits)>(this->bits ^ other.bits)};
}
StyleAlignFlags& operator^=(const StyleAlignFlags& other) {
Expand Down
30 changes: 15 additions & 15 deletions tests/expectations/bitflags.cpp
Expand Up @@ -10,27 +10,27 @@
struct AlignFlags {
uint8_t bits;

explicit operator bool() const {
constexpr explicit operator bool() const {
return !!bits;
}
AlignFlags operator~() const {
constexpr AlignFlags operator~() const {
return {static_cast<decltype(bits)>(~bits)};
}
AlignFlags operator|(const AlignFlags& other) const {
constexpr AlignFlags operator|(const AlignFlags& other) const {
return {static_cast<decltype(bits)>(this->bits | other.bits)};
}
AlignFlags& operator|=(const AlignFlags& other) {
*this = (*this | other);
return *this;
}
AlignFlags operator&(const AlignFlags& other) const {
constexpr AlignFlags operator&(const AlignFlags& other) const {
return {static_cast<decltype(bits)>(this->bits & other.bits)};
}
AlignFlags& operator&=(const AlignFlags& other) {
*this = (*this & other);
return *this;
}
AlignFlags operator^(const AlignFlags& other) const {
constexpr AlignFlags operator^(const AlignFlags& other) const {
return {static_cast<decltype(bits)>(this->bits ^ other.bits)};
}
AlignFlags& operator^=(const AlignFlags& other) {
Expand All @@ -55,27 +55,27 @@ constexpr static const AlignFlags AlignFlags_MIXED_SELF = AlignFlags{ /* .bits =
struct DebugFlags {
uint32_t bits;

explicit operator bool() const {
constexpr explicit operator bool() const {
return !!bits;
}
DebugFlags operator~() const {
constexpr DebugFlags operator~() const {
return {static_cast<decltype(bits)>(~bits)};
}
DebugFlags operator|(const DebugFlags& other) const {
constexpr DebugFlags operator|(const DebugFlags& other) const {
return {static_cast<decltype(bits)>(this->bits | other.bits)};
}
DebugFlags& operator|=(const DebugFlags& other) {
*this = (*this | other);
return *this;
}
DebugFlags operator&(const DebugFlags& other) const {
constexpr DebugFlags operator&(const DebugFlags& other) const {
return {static_cast<decltype(bits)>(this->bits & other.bits)};
}
DebugFlags& operator&=(const DebugFlags& other) {
*this = (*this & other);
return *this;
}
DebugFlags operator^(const DebugFlags& other) const {
constexpr DebugFlags operator^(const DebugFlags& other) const {
return {static_cast<decltype(bits)>(this->bits ^ other.bits)};
}
DebugFlags& operator^=(const DebugFlags& other) {
Expand All @@ -89,27 +89,27 @@ constexpr static const DebugFlags DebugFlags_BIGGEST_ALLOWED = DebugFlags{ /* .b
struct LargeFlags {
uint64_t bits;

explicit operator bool() const {
constexpr explicit operator bool() const {
return !!bits;
}
LargeFlags operator~() const {
constexpr LargeFlags operator~() const {
return {static_cast<decltype(bits)>(~bits)};
}
LargeFlags operator|(const LargeFlags& other) const {
constexpr LargeFlags operator|(const LargeFlags& other) const {
return {static_cast<decltype(bits)>(this->bits | other.bits)};
}
LargeFlags& operator|=(const LargeFlags& other) {
*this = (*this | other);
return *this;
}
LargeFlags operator&(const LargeFlags& other) const {
constexpr LargeFlags operator&(const LargeFlags& other) const {
return {static_cast<decltype(bits)>(this->bits & other.bits)};
}
LargeFlags& operator&=(const LargeFlags& other) {
*this = (*this & other);
return *this;
}
LargeFlags operator^(const LargeFlags& other) const {
constexpr LargeFlags operator^(const LargeFlags& other) const {
return {static_cast<decltype(bits)>(this->bits ^ other.bits)};
}
LargeFlags& operator^=(const LargeFlags& other) {
Expand Down

0 comments on commit 0ee47b3

Please sign in to comment.