[cxx] int vs. enum -- bit overload version (#10274)
* [cxx] int vs. enum.
There are at least three or so approaches to this.
1. Sprinkle around casts.
2. Overload operators.
2a. Bit-only (| & ^ |= &= ^=) This PR.
2b. Also math (+ - ++ -- == !=)
3. typedef to int instead (https://github.com/mono/mono/pull/10231)
They all have tradeoffs.
1. Casts: The most line damage. Not huge, but the most.
2. Overloads: New idiom to some but an old idiom. Supported in this way by windows.h even.
This is the most "C++y solution".
3. int: Highest level of source compat and semantic compat. Least line damage (just
change the declarations). Least debuggable and least typesafe.
In terms of semantic compat, even in C the guarantees aren't particularly strong.
Some enums will be int, some unsigned, depending on the values and the compiler.
Perhaps even other types, but I doubt it.
I observe C++ compilers don't tend toward unsigned the same way, so switching
to C++ will on some platforms lose unsignedness. Given we didn't have it portably
anyway, should be ok.
A typesafe enum has the properties that enum A cannot be silently assigned to enum B (ok,
there might be a warning), or from an integer.
A typesafe enum, bitfield or otherwise, can/will be shown symbolically by a debugger.
(lldb does not handle bitfields, only strict enums)
A C enum might be debuggable, w/o typesafety.
A C enum can be freely mixed with other enums and integers.
A C++ enum is more restricted.
Using typedef int, is a maybe surprising option, but does provide the closest meaning to C enum.
Per guidance, this PR also changes one enum to #defines + int.
* PR: "mono" => "g"
"T" => "type"
static_cast where it works (not to reference)
Use templatized typedef instead of macro, if it works on g++4.4.
Add test.
Provide to build eglib tests.
Borrow CXXFLAGS_COMMON from https://github.com/mono/mono/pull/10271.
Add some const to test harness.
* g++4.4 compat (not quite C++11) -- use macro, not template typedef.
* Fix real problem with aliasing seen with g++4.4.
Use attribute(may_alias) when casting pointers/references.
* Add mono/eglib/test/enum.cpp.
20 files changed: