From 230042b7539da8086d891ab7d0c3cc02c63436f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Sun, 8 Dec 2019 17:51:25 +0100 Subject: [PATCH] Implement more operators for bitflags. --- src/bindgen/ir/structure.rs | 99 ++++++++++------------- tests/expectations/associated_in_body.cpp | 10 +++ tests/expectations/bitflags.cpp | 10 +++ 3 files changed, 64 insertions(+), 55 deletions(-) diff --git a/src/bindgen/ir/structure.rs b/src/bindgen/ir/structure.rs index b6c9be056..a45f7f9f1 100644 --- a/src/bindgen/ir/structure.rs +++ b/src/bindgen/ir/structure.rs @@ -173,6 +173,45 @@ impl Struct { self.documentation.clone(), ) } + + fn emit_bitflags_binop( + &self, + operator: char, + other: &str, + out: &mut SourceWriter, + ) { + out.new_line(); + write!( + out, + "{} operator{}(const {}& {}) const", + self.export_name(), + operator, + self.export_name(), + other + ); + out.open_brace(); + write!( + out, + "return {{static_cast(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 { @@ -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(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(this->bits & {}.bits)}};", - other - ); + write!(out, "return {{static_cast(~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 }; diff --git a/tests/expectations/associated_in_body.cpp b/tests/expectations/associated_in_body.cpp index da25886ce..db4596dcf 100644 --- a/tests/expectations/associated_in_body.cpp +++ b/tests/expectations/associated_in_body.cpp @@ -12,6 +12,9 @@ struct StyleAlignFlags { explicit operator bool() const { return !!bits; } + StyleAlignFlags operator~() const { + return {static_cast(~bits)}; + } StyleAlignFlags operator|(const StyleAlignFlags& other) const { return {static_cast(this->bits | other.bits)}; } @@ -26,6 +29,13 @@ struct StyleAlignFlags { *this = (*this & other); return *this; } + StyleAlignFlags operator^(const StyleAlignFlags& other) const { + return {static_cast(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; diff --git a/tests/expectations/bitflags.cpp b/tests/expectations/bitflags.cpp index 96ec1ed80..16c9fb9fd 100644 --- a/tests/expectations/bitflags.cpp +++ b/tests/expectations/bitflags.cpp @@ -12,6 +12,9 @@ struct AlignFlags { explicit operator bool() const { return !!bits; } + AlignFlags operator~() const { + return {static_cast(~bits)}; + } AlignFlags operator|(const AlignFlags& other) const { return {static_cast(this->bits | other.bits)}; } @@ -26,6 +29,13 @@ struct AlignFlags { *this = (*this & other); return *this; } + AlignFlags operator^(const AlignFlags& other) const { + return {static_cast(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 };