Francisco Jerez <curroje...@riseup.net> writes: > Ian Romanick <i...@freedesktop.org> writes: > >> On 08/26/2013 01:10 PM, Francisco Jerez wrote: >>>[...] >>> The thing is that defining bitwise operators separately for each enum >>> type, as this patch and the macro solution do, doesn't stop the compiler >>> From using the corresponding built-in integer operators when it doesn't >>> find a match among the user-defined ones. That means that if we have >>> two bitfield enumerants from two different disjoint types >>> e.g. "SEASON_OF_THE_YEAR_SUMMER" and a "CPU_ARCHITECTURE_I386", the >>> compiler is still going to accept expressions like >>> "SEASON_OF_THE_YEAR_SUMMER | CPU_ARCHITECTURE_I386", which might not be >>> what had been expected if the BRW_CXX_ENUM_OPS macro was used in an >>> attempt to improve the code's type safety. >> >> This sounds insane. >> >> If there are no operator overloads, the compiler rejects: >> >> enum foo f(enum foo a, enum foo b) >> { >> return a | b; >> } >> > > Here both a and b would be implicitly converted to integers which are > then or'ed together using the built-in '|' operator yielding an integer. > Using the result as return value of your "enum foo" function fails > because in C++ integers are not implicitly convertible to enum types. > >> Then we add operloads: >> >> enum foo operator|(enum foo, enum foo); >> enum bar operator|(enum bar, enum bar); >> >> And now the compiler will accept: >> >> unsigned f(enum foo a, enum bar b) >> { >> return a | b; >> } >> > That's accepted because both a and b are converted to integers as > before, giving an integer as result, which can be implicitly converted > to your unsigned return type just fine. It's easy to avoid that though > by defining a general overload: > > template<typename T, typename S> T operator|(T, S); > > for any bitfield types "T" and "S" that includes a static assertion > within its definition to make sure that both types are indeed the same. > > In your example above the compiler would find an exact match during > overload resolution (our "operator|<foo, bar>(foo, bar);") so it > wouldn't have to bother with implicit argument conversions. The > instantiation of that template would fail thanks to the static assertion > requiring both T and S to be equal. > > I hope this makes the idea a bit clearer. > >> That can't be right. Am I missing something? Or am I reinforcing my >> point about not being ready for this level of C++ ninjitsu...
This is way overcomplicated. I think we're doing just fine with the status quo of #defines for our bitfields with namespaced names.
pgptvgKWfB3KF.pgp
Description: PGP signature
_______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev