4 ms·
Yes it would need to be: if ((mask & (WGPUColorWriteMask_Alpha|WGPUColorWriteMask_Blue)) == (WGPUColorWriteMask_Alpha|WGPUColorWriteMask_Blue)) { ... } ..
by flohofwoe 4y ago
Yes it would need to be:
if ((mask & (WGPUColorWriteMask_Alpha|WGPUColorWriteMask_Blue)) == (WGPUColorWriteMask_Alpha|WGPUColorWriteMask_Blue)) { ... }
...which is quite a mouthful.
- deleted 4y ago[deleted]
- tempodox 4y agoIn C I'm using a macro for stuff like that (improving readability, avoiding errors). In Zig I could use a `comptime` function, I presume?
- messe 4y agoIt depends on what else you’re doing. In this situation normal function would suffice in either C or Zig.
- chrismorgan 4y agoI’ve definitely desired an operator that combines these before. I’ve settled on &== as the best syntax in C-style languages, with a &== b being equivalent to a & b == b (but with a single evaluation of b). 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.
- magicalhippo 4y ago> I find only two very minor problems with it: firstly, that it’s not commutative Why is that a problem? That is, if a has additional bits set compared to b, then ((a & b) == b) != ((b & a) == a), no?
- chrismorgan 4y agoOf common operators, / and - are the only ones that aren’t commutative. 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.
- magicalhippo 4y agoYeah ok. I'd consider that just a thing you gotta know. Like how for certain floating point values (a / b) * (c / d) can be fine while (a * c) / (b * d) gives you +/- infinity. It's a separate operator after all, one I also miss a lot...
- beeforpork 4y agoFaszinating: I also thought about exactly '&==' in the past. It seems to be natural choice for this. 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.
- chrismorgan 4y agoNow I’m trying to decide if you make it better or worse by replacing the == 0 with simple logical negation: 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)`.
- silvestrov 4y agoYou could also play the game of pretending that the scalar is an object and allow for syntactical sugar like: if (mask.contains(WGPUColorWriteMask_Alpha) || mask.contains(WGPUColorWriteMask_Blue)) { ... }
- chrismorgan 4y agoFun fact: Rust’s bitflags macro crate generates just this, https://docs.rs/bitflags/latest/bitflags/example_generated/struct.Flags.html#method.contains https://docs.rs/bitflags/latest/bitflags/example_generated/s.... // 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) { … }
- suyjuris 4y agoYou can also do it as follows: if (!(~mask & (WGPUColorWriteMask_Alpha|WGPUColorWriteMask_Blue))) { ... } Not quite as long but perhaps less readable.
- lobo_tuerto 4y agoWhat about? if (mask & WGPUColorWriteMask_Alpha & WGPUColorWriteMask_Blue) { // alpha and blue are set.. }
- ElectricalUnion 4y ago> `mask & WGPUColorWriteMask_Alpha & WGPUColorWriteMask_Blue` If WGPUColorWriteMask_Alpha and WGPUColorWriteMask_Blue doesn't share bits, isn't this garanteed 100% to be false?
- childintime 4y agoI use: if (all_of(mask, WGPUColorWriteMask_Alpha | WGPUColorWriteMask_Blue)) with all_of() being a #define. Likewise none_of(), any_of(). No need for special operators.
- tzs 4y agoIf you are willing to assume that the masks each only have 1 bit set, this would be less of a mouthful although it would draw other objections: 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 https://ziglang.org/documentation/master/#popCount
- nurbl 4y agoI think the point of the example is that in zig you'd just do if (mask.alpha and mask.blue) {