Skip to content

Commit

Permalink
Add bitwise operators for flag enums (#1413)
Browse files Browse the repository at this point in the history
  • Loading branch information
kennykerr committed Jan 3, 2022
1 parent dfc2528 commit de0d697
Show file tree
Hide file tree
Showing 85 changed files with 3,937 additions and 6 deletions.
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

0 comments on commit de0d697

Please sign in to comment.