if ((mask & (WGPUColorWriteMask_Alpha|WGPUColorWriteMask_Blue)) == (WGPUColorWriteMask_Alpha|WGPUColorWriteMask_Blue)) { ... }
...which is quite a mouthful. if ((mask & (WGPUColorWriteMask_Alpha|WGPUColorWriteMask_Blue)) == (WGPUColorWriteMask_Alpha|WGPUColorWriteMask_Blue)) { ... }
...which is quite a mouthful. if (mask &== WGPUColorWriteMask_Alpha|WGPUColorWriteMask_Blue) { … }
I find only two very minor problems with it: firstly, that it’s not commutative (that is, a &== b is not equivalent to b &== a). Secondly, that it can be confused with the bitwise-and assignment operator &= (a &= b being equivalent to a = a & b for singly-evaluated lvalue a).I’d then add |== for consistency and because it is conceivably useful. ^== is tempting, but since a ^== b would be just another spelling of a == 0, I’d skip it.
Why is that a problem? That is, if a has additional bits set compared to b, then ((a & b) == b) != ((b & a) == a), no?
For equality comparisons, there are two opposing conventions: actual == expected (the more popular, in my experience), and expected == actual (by no means rare). Having &== and |== be order-sensitive (though there’s absolutely no question in my mind about what the ordering should be) is mildly unfortunate.
It’s very minor.
It's a separate operator after all, one I also miss a lot...
But then, continuing that thinking, if you have '&==', you'd also need '&!=' -- that looks really confusing.
Can't we turn that into a '==0' test somehow? Maybe '^&', because '((a ^ b) & b) == 0' is equivalent to '(a & b) == b'. And, as somehow said: '~&' also works: '(~a & b) == 0' is also equivalent to '(a & b) == b'.
if ((a ~& b) == 0) { ... }
Wait -- we can swap that into '&~' and we're back in C. However, it reverses the logical order, with the test bits first: if ((b & ~a) == 0) { ... }
if (((WGPUColorWriteMask_Alpha|WGPUColorWriteMask_Blue) & ~mask) == 0) {
...
}
So we're back -- this is standard C now. But I find it incomprehensible. if (!(b & ~a)) { … }
if (!((WGPUColorWriteMask_Alpha|WGPUColorWriteMask_Blue) & ~mask)) { … }
if (!(~a & b)) { … }
if (!(~mask & (WGPUColorWriteMask_Alpha|WGPUColorWriteMask_Blue))) { … }
Actually, that latter makes a little more intuitive sense to me because of how ! and ~ are both negation¹, so they kinda cancel out and leave just the masking. Kinda.—⁂—
¹ Fun fact: Rust uses ! for both logical and bitwise negation, backed by core::ops::Not, with bool → bool and {integer} → {integer}, since bool is a proper type and there’s no boolean coercion anywhere—so you would have to stick with `== 0` in Rust, though in practice you’d probably go all typey with the bitflags crate’s macro to generate good types with some handy extra methods, and write `mask.contains(WgpuColorWriteMask::Alpha | WgpuColorWriteMask::Blue)`.
if (mask.contains(WGPUColorWriteMask_Alpha) || mask.contains(WGPUColorWriteMask_Blue)) { ... } // To check for either flag:
if mask.contains(WgpuColorWriteMask::Alpha) || mask.contains(WgpuColorWriteMask::Blue) { … }
if mask.intersects(WgpuColorWriteMask::Alpha | WgpuColorWriteMask::Blue) { … }
// To check for both flags:
if mask.contains(WgpuColorWriteMask::Alpha | WgpuColorWriteMask::Blue) { … } if (!(~mask & (WGPUColorWriteMask_Alpha|WGPUColorWriteMask_Blue))) { ... }
Not quite as long but perhaps less readable. if (all_of(mask, WGPUColorWriteMask_Alpha | WGPUColorWriteMask_Blue))
with all_of() being a #define. Likewise none_of(), any_of().No need for special operators.
if (@popCount(mask & (WGPUColorWriteMask_Alpha|WGPUColorWriteMask_Blue)) == 2)
I do not know Zig, so the syntax might not be right. I did check to see that it has popcount [1].If it has some concise way to flip all the bits, then this would be another possibility that isn't too verbose, but might raise other objections. Let fmask be mask with all the bits flipped (how would one do that in Zig?).
if ((fmask & (WGPUColorWriteMask_Alpha|WGPUColorWriteMask_Blue)) == 0)
[1] https://ziglang.org/documentation/master/#popCount if (mask.alpha and mask.blue) { if (mask & WGPUColorWriteMask_Alpha & WGPUColorWriteMask_Blue) {
// alpha and blue are set..
}If WGPUColorWriteMask_Alpha and WGPUColorWriteMask_Blue doesn't share bits, isn't this garanteed 100% to be false?