Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add bitwise operators for flag enums #1413

Merged
merged 1 commit into from Jan 3, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.toml
Expand Up @@ -9,6 +9,7 @@ members = [
"crates/tests/win32/*",
"crates/tests/core",
"crates/tests/debug",
"crates/tests/enums",
"crates/tests/sys",
]
exclude = ["crates/tests/component"]
36 changes: 36 additions & 0 deletions crates/libs/bindgen/src/enums.rs
Expand Up @@ -93,6 +93,42 @@ pub fn gen(def: &TypeDef, gen: &Gen) -> TokenStream {
}
}
});

if def.has_flags() {
tokens.combine(&quote! {
impl ::core::ops::BitOr for #ident {
type Output = Self;

fn bitor(self, other: Self) -> Self {
Self(self.0 | other.0)
}
}
impl ::core::ops::BitAnd for #ident {
type Output = Self;

fn bitand(self, other: Self) -> Self {
Self(self.0 & other.0)
}
}
impl ::core::ops::BitOrAssign for #ident {
fn bitor_assign(&mut self, other: Self) {
self.0.bitor_assign(other.0)
}
}
impl ::core::ops::BitAndAssign for #ident {
fn bitand_assign(&mut self, other: Self) {
self.0.bitand_assign(other.0)
}
}
impl ::core::ops::Not for #ident {
type Output = Self;

fn not(self) -> Self {
Self(self.0.not())
}
}
});
}
}

if def.is_winrt() {
Expand Down
6 changes: 1 addition & 5 deletions crates/libs/gen/src/enum.rs
Expand Up @@ -4,13 +4,9 @@ pub fn gen_enum(def: &TypeDef, gen: &Gen, include: TypeInclude) -> TokenStream {
let name = gen_type_name(def, gen);
let underlying_type = def.underlying_type();

// WinRT enums don't have the flags attribute but are paritioned merely based
// on whether they are signed.
let bitwise = matches!(underlying_type, ElementType::U32);

// Win32 enums sadly don't use unsigned values uniformly so we need to rely
// on the flags attribute.
let bitwise = if bitwise || def.has_flags() {
let bitwise = if def.has_flags() {
quote! {
impl ::core::ops::BitOr for #name {
type Output = Self;
Expand Down
4 changes: 3 additions & 1 deletion crates/libs/reader/src/tables/type_def.rs
Expand Up @@ -494,7 +494,9 @@ impl TypeDef {
}

pub fn has_flags(&self) -> bool {
self.has_attribute("FlagsAttribute")
// Win32 enums use the Flags attribute. WinRT enums don't have the Flags attribute but are paritioned merely based
// on whether they are signed.
self.has_attribute("FlagsAttribute") || self.underlying_type() == ElementType::U32
}

pub fn is_exclusive(&self) -> bool {
Expand Down
Expand Up @@ -1338,6 +1338,34 @@ impl ::core::fmt::Debug for AppointmentDaysOfWeek {
f.debug_tuple("AppointmentDaysOfWeek").field(&self.0).finish()
}
}
impl ::core::ops::BitOr for AppointmentDaysOfWeek {
type Output = Self;
fn bitor(self, other: Self) -> Self {
Self(self.0 | other.0)
}
}
impl ::core::ops::BitAnd for AppointmentDaysOfWeek {
type Output = Self;
fn bitand(self, other: Self) -> Self {
Self(self.0 & other.0)
}
}
impl ::core::ops::BitOrAssign for AppointmentDaysOfWeek {
fn bitor_assign(&mut self, other: Self) {
self.0.bitor_assign(other.0)
}
}
impl ::core::ops::BitAndAssign for AppointmentDaysOfWeek {
fn bitand_assign(&mut self, other: Self) {
self.0.bitand_assign(other.0)
}
}
impl ::core::ops::Not for AppointmentDaysOfWeek {
type Output = Self;
fn not(self) -> Self {
Self(self.0.not())
}
}
unsafe impl ::windows::core::RuntimeType for AppointmentDaysOfWeek {
const SIGNATURE: ::windows::core::ConstBuffer = ::windows::core::ConstBuffer::from_slice(b"enum(Windows.ApplicationModel.Appointments.AppointmentDaysOfWeek;u4)");
}
Expand Down Expand Up @@ -3627,6 +3655,34 @@ impl ::core::fmt::Debug for FindAppointmentCalendarsOptions {
f.debug_tuple("FindAppointmentCalendarsOptions").field(&self.0).finish()
}
}
impl ::core::ops::BitOr for FindAppointmentCalendarsOptions {
type Output = Self;
fn bitor(self, other: Self) -> Self {
Self(self.0 | other.0)
}
}
impl ::core::ops::BitAnd for FindAppointmentCalendarsOptions {
type Output = Self;
fn bitand(self, other: Self) -> Self {
Self(self.0 & other.0)
}
}
impl ::core::ops::BitOrAssign for FindAppointmentCalendarsOptions {
fn bitor_assign(&mut self, other: Self) {
self.0.bitor_assign(other.0)
}
}
impl ::core::ops::BitAndAssign for FindAppointmentCalendarsOptions {
fn bitand_assign(&mut self, other: Self) {
self.0.bitand_assign(other.0)
}
}
impl ::core::ops::Not for FindAppointmentCalendarsOptions {
type Output = Self;
fn not(self) -> Self {
Self(self.0.not())
}
}
unsafe impl ::windows::core::RuntimeType for FindAppointmentCalendarsOptions {
const SIGNATURE: ::windows::core::ConstBuffer = ::windows::core::ConstBuffer::from_slice(b"enum(Windows.ApplicationModel.Appointments.FindAppointmentCalendarsOptions;u4)");
}
Expand Down
Expand Up @@ -753,6 +753,34 @@ impl ::core::fmt::Debug for PhoneLineProperties {
f.debug_tuple("PhoneLineProperties").field(&self.0).finish()
}
}
impl ::core::ops::BitOr for PhoneLineProperties {
type Output = Self;
fn bitor(self, other: Self) -> Self {
Self(self.0 | other.0)
}
}
impl ::core::ops::BitAnd for PhoneLineProperties {
type Output = Self;
fn bitand(self, other: Self) -> Self {
Self(self.0 & other.0)
}
}
impl ::core::ops::BitOrAssign for PhoneLineProperties {
fn bitor_assign(&mut self, other: Self) {
self.0.bitor_assign(other.0)
}
}
impl ::core::ops::BitAndAssign for PhoneLineProperties {
fn bitand_assign(&mut self, other: Self) {
self.0.bitand_assign(other.0)
}
}
impl ::core::ops::Not for PhoneLineProperties {
type Output = Self;
fn not(self) -> Self {
Self(self.0.not())
}
}
unsafe impl ::windows::core::RuntimeType for PhoneLineProperties {
const SIGNATURE: ::windows::core::ConstBuffer = ::windows::core::ConstBuffer::from_slice(b"enum(Windows.ApplicationModel.Calls.Background.PhoneLineProperties;u4)");
}
Expand Down
56 changes: 56 additions & 0 deletions crates/libs/windows/src/Windows/ApplicationModel/Calls/mod.rs
Expand Up @@ -2917,6 +2917,34 @@ impl ::core::fmt::Debug for PhoneCallHistoryEntryQueryDesiredMedia {
f.debug_tuple("PhoneCallHistoryEntryQueryDesiredMedia").field(&self.0).finish()
}
}
impl ::core::ops::BitOr for PhoneCallHistoryEntryQueryDesiredMedia {
type Output = Self;
fn bitor(self, other: Self) -> Self {
Self(self.0 | other.0)
}
}
impl ::core::ops::BitAnd for PhoneCallHistoryEntryQueryDesiredMedia {
type Output = Self;
fn bitand(self, other: Self) -> Self {
Self(self.0 & other.0)
}
}
impl ::core::ops::BitOrAssign for PhoneCallHistoryEntryQueryDesiredMedia {
fn bitor_assign(&mut self, other: Self) {
self.0.bitor_assign(other.0)
}
}
impl ::core::ops::BitAndAssign for PhoneCallHistoryEntryQueryDesiredMedia {
fn bitand_assign(&mut self, other: Self) {
self.0.bitand_assign(other.0)
}
}
impl ::core::ops::Not for PhoneCallHistoryEntryQueryDesiredMedia {
type Output = Self;
fn not(self) -> Self {
Self(self.0.not())
}
}
unsafe impl ::windows::core::RuntimeType for PhoneCallHistoryEntryQueryDesiredMedia {
const SIGNATURE: ::windows::core::ConstBuffer = ::windows::core::ConstBuffer::from_slice(b"enum(Windows.ApplicationModel.Calls.PhoneCallHistoryEntryQueryDesiredMedia;u4)");
}
Expand Down Expand Up @@ -6143,6 +6171,34 @@ impl ::core::fmt::Debug for VoipPhoneCallMedia {
f.debug_tuple("VoipPhoneCallMedia").field(&self.0).finish()
}
}
impl ::core::ops::BitOr for VoipPhoneCallMedia {
type Output = Self;
fn bitor(self, other: Self) -> Self {
Self(self.0 | other.0)
}
}
impl ::core::ops::BitAnd for VoipPhoneCallMedia {
type Output = Self;
fn bitand(self, other: Self) -> Self {
Self(self.0 & other.0)
}
}
impl ::core::ops::BitOrAssign for VoipPhoneCallMedia {
fn bitor_assign(&mut self, other: Self) {
self.0.bitor_assign(other.0)
}
}
impl ::core::ops::BitAndAssign for VoipPhoneCallMedia {
fn bitand_assign(&mut self, other: Self) {
self.0.bitand_assign(other.0)
}
}
impl ::core::ops::Not for VoipPhoneCallMedia {
type Output = Self;
fn not(self) -> Self {
Self(self.0.not())
}
}
unsafe impl ::windows::core::RuntimeType for VoipPhoneCallMedia {
const SIGNATURE: ::windows::core::ConstBuffer = ::windows::core::ConstBuffer::from_slice(b"enum(Windows.ApplicationModel.Calls.VoipPhoneCallMedia;u4)");
}
Expand Down
84 changes: 84 additions & 0 deletions crates/libs/windows/src/Windows/ApplicationModel/Contacts/mod.rs
Expand Up @@ -1183,6 +1183,34 @@ impl ::core::fmt::Debug for ContactAnnotationOperations {
f.debug_tuple("ContactAnnotationOperations").field(&self.0).finish()
}
}
impl ::core::ops::BitOr for ContactAnnotationOperations {
type Output = Self;
fn bitor(self, other: Self) -> Self {
Self(self.0 | other.0)
}
}
impl ::core::ops::BitAnd for ContactAnnotationOperations {
type Output = Self;
fn bitand(self, other: Self) -> Self {
Self(self.0 & other.0)
}
}
impl ::core::ops::BitOrAssign for ContactAnnotationOperations {
fn bitor_assign(&mut self, other: Self) {
self.0.bitor_assign(other.0)
}
}
impl ::core::ops::BitAndAssign for ContactAnnotationOperations {
fn bitand_assign(&mut self, other: Self) {
self.0.bitand_assign(other.0)
}
}
impl ::core::ops::Not for ContactAnnotationOperations {
type Output = Self;
fn not(self) -> Self {
Self(self.0.not())
}
}
unsafe impl ::windows::core::RuntimeType for ContactAnnotationOperations {
const SIGNATURE: ::windows::core::ConstBuffer = ::windows::core::ConstBuffer::from_slice(b"enum(Windows.ApplicationModel.Contacts.ContactAnnotationOperations;u4)");
}
Expand Down Expand Up @@ -6304,6 +6332,34 @@ impl ::core::fmt::Debug for ContactQueryDesiredFields {
f.debug_tuple("ContactQueryDesiredFields").field(&self.0).finish()
}
}
impl ::core::ops::BitOr for ContactQueryDesiredFields {
type Output = Self;
fn bitor(self, other: Self) -> Self {
Self(self.0 | other.0)
}
}
impl ::core::ops::BitAnd for ContactQueryDesiredFields {
type Output = Self;
fn bitand(self, other: Self) -> Self {
Self(self.0 & other.0)
}
}
impl ::core::ops::BitOrAssign for ContactQueryDesiredFields {
fn bitor_assign(&mut self, other: Self) {
self.0.bitor_assign(other.0)
}
}
impl ::core::ops::BitAndAssign for ContactQueryDesiredFields {
fn bitand_assign(&mut self, other: Self) {
self.0.bitand_assign(other.0)
}
}
impl ::core::ops::Not for ContactQueryDesiredFields {
type Output = Self;
fn not(self) -> Self {
Self(self.0.not())
}
}
unsafe impl ::windows::core::RuntimeType for ContactQueryDesiredFields {
const SIGNATURE: ::windows::core::ConstBuffer = ::windows::core::ConstBuffer::from_slice(b"enum(Windows.ApplicationModel.Contacts.ContactQueryDesiredFields;u4)");
}
Expand Down Expand Up @@ -6504,6 +6560,34 @@ impl ::core::fmt::Debug for ContactQuerySearchFields {
f.debug_tuple("ContactQuerySearchFields").field(&self.0).finish()
}
}
impl ::core::ops::BitOr for ContactQuerySearchFields {
type Output = Self;
fn bitor(self, other: Self) -> Self {
Self(self.0 | other.0)
}
}
impl ::core::ops::BitAnd for ContactQuerySearchFields {
type Output = Self;
fn bitand(self, other: Self) -> Self {
Self(self.0 & other.0)
}
}
impl ::core::ops::BitOrAssign for ContactQuerySearchFields {
fn bitor_assign(&mut self, other: Self) {
self.0.bitor_assign(other.0)
}
}
impl ::core::ops::BitAndAssign for ContactQuerySearchFields {
fn bitand_assign(&mut self, other: Self) {
self.0.bitand_assign(other.0)
}
}
impl ::core::ops::Not for ContactQuerySearchFields {
type Output = Self;
fn not(self) -> Self {
Self(self.0.not())
}
}
unsafe impl ::windows::core::RuntimeType for ContactQuerySearchFields {
const SIGNATURE: ::windows::core::ConstBuffer = ::windows::core::ConstBuffer::from_slice(b"enum(Windows.ApplicationModel.Contacts.ContactQuerySearchFields;u4)");
}
Expand Down
Expand Up @@ -385,6 +385,34 @@ impl ::core::fmt::Debug for CoreDragUIContentMode {
f.debug_tuple("CoreDragUIContentMode").field(&self.0).finish()
}
}
impl ::core::ops::BitOr for CoreDragUIContentMode {
type Output = Self;
fn bitor(self, other: Self) -> Self {
Self(self.0 | other.0)
}
}
impl ::core::ops::BitAnd for CoreDragUIContentMode {
type Output = Self;
fn bitand(self, other: Self) -> Self {
Self(self.0 & other.0)
}
}
impl ::core::ops::BitOrAssign for CoreDragUIContentMode {
fn bitor_assign(&mut self, other: Self) {
self.0.bitor_assign(other.0)
}
}
impl ::core::ops::BitAndAssign for CoreDragUIContentMode {
fn bitand_assign(&mut self, other: Self) {
self.0.bitand_assign(other.0)
}
}
impl ::core::ops::Not for CoreDragUIContentMode {
type Output = Self;
fn not(self) -> Self {
Self(self.0.not())
}
}
unsafe impl ::windows::core::RuntimeType for CoreDragUIContentMode {
const SIGNATURE: ::windows::core::ConstBuffer = ::windows::core::ConstBuffer::from_slice(b"enum(Windows.ApplicationModel.DataTransfer.DragDrop.Core.CoreDragUIContentMode;u4)");
}
Expand Down