Skip to content

Commit

Permalink
Implement more operators for bitflags.
Browse files Browse the repository at this point in the history
  • Loading branch information
emilio committed Dec 8, 2019
1 parent e0fe4e4 commit 230042b
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 55 deletions.
99 changes: 44 additions & 55 deletions src/bindgen/ir/structure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,45 @@ impl Struct {
self.documentation.clone(),
)
}

fn emit_bitflags_binop<F: Write>(
&self,
operator: char,
other: &str,
out: &mut SourceWriter<F>,
) {
out.new_line();
write!(
out,
"{} operator{}(const {}& {}) const",
self.export_name(),
operator,
self.export_name(),
other
);
out.open_brace();
write!(
out,
"return {{static_cast<decltype(bits)>(this->bits {} {}.bits)}};",
operator, other
);
out.close_brace(false);

out.new_line();
write!(
out,
"{}& operator{}=(const {}& {})",
self.export_name(),
operator,
self.export_name(),
other
);
out.open_brace();
write!(out, "*this = (*this {} {});", operator, other);
out.new_line();
write!(out, "return *this;");
out.close_brace(false);
}
}

impl Item for Struct {
Expand Down Expand Up @@ -459,64 +498,14 @@ impl Source for Struct {
out.close_brace(false);

out.new_line();
write!(
out,
"{} operator|(const {}& {}) const",
self.export_name(),
self.export_name(),
other
);
out.open_brace();
write!(
out,
"return {{static_cast<decltype(bits)>(this->bits | {}.bits)}};",
other
);
out.close_brace(false);

out.new_line();
write!(
out,
"{}& operator|=(const {}& {})",
self.export_name(),
self.export_name(),
other
);
out.open_brace();
write!(out, "*this = (*this | {});", other);
out.new_line();
write!(out, "return *this;");
out.close_brace(false);

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

out.new_line();
write!(
out,
"{}& operator&=(const {}& {})",
self.export_name(),
self.export_name(),
other
);
out.open_brace();
write!(out, "*this = (*this & {});", other);
out.new_line();
write!(out, "return *this;");
out.close_brace(false);
self.emit_bitflags_binop('|', &other, out);
self.emit_bitflags_binop('&', &other, out);
self.emit_bitflags_binop('^', &other, out);
}

let skip_fields = if self.is_tagged { 1 } else { 0 };
Expand Down
10 changes: 10 additions & 0 deletions tests/expectations/associated_in_body.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ struct StyleAlignFlags {
explicit operator bool() const {
return !!bits;
}
StyleAlignFlags operator~() const {
return {static_cast<decltype(bits)>(~bits)};
}
StyleAlignFlags operator|(const StyleAlignFlags& other) const {
return {static_cast<decltype(bits)>(this->bits | other.bits)};
}
Expand All @@ -26,6 +29,13 @@ struct StyleAlignFlags {
*this = (*this & other);
return *this;
}
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;
}
static const StyleAlignFlags AUTO;
static const StyleAlignFlags NORMAL;
static const StyleAlignFlags START;
Expand Down
10 changes: 10 additions & 0 deletions tests/expectations/bitflags.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ struct AlignFlags {
explicit operator bool() const {
return !!bits;
}
AlignFlags operator~() const {
return {static_cast<decltype(bits)>(~bits)};
}
AlignFlags operator|(const AlignFlags& other) const {
return {static_cast<decltype(bits)>(this->bits | other.bits)};
}
Expand All @@ -26,6 +29,13 @@ struct AlignFlags {
*this = (*this & other);
return *this;
}
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;
}
};
static const AlignFlags AlignFlags_AUTO = AlignFlags{ /* .bits = */ 0 };
static const AlignFlags AlignFlags_NORMAL = AlignFlags{ /* .bits = */ 1 };
Expand Down

0 comments on commit 230042b

Please sign in to comment.