enum.h tries to automatically detect whether it is running with C++11 support.
If not, it emits alternative code that is supposed to work on compilers
supporting C++98 and variadic macros. This code is largely interface-compatible
with the C++11 code, with the following semantic differences:
- No compile-time stringization. This is done upon first use of a function other
than to_integral.
- Implicit conversion to integral types. This is due to the lack of enum class
support.
- The values _name, _names, _values are replaced with functions _name_, _names_,
_values_.
A Better Enum is normally implicitly convertible to its internal enum type,
which makes it then implicitly convertible to an integer as well. The former
conversion is necessary for Better Enums to be usable in switch statements.
This change makes it possible to define BETTER_ENUMS_SAFER_SWITCH, which makes
Better Enums convert to an enum class, preventing the implicit conversion to
integers. The drawback is that switch cases have to be written as
case Enum::_Case::A:
instead of
case Enum::A:
The interface is now uniformly constexpr, including to_string and the _names
iterable. Without the weak symbol, the remaining code is also entirely standard
C++.
The compile-time string trimming code in this commit has a negative impact on
performance. The performance test is now twice as slow as including <iostream>,
whereas before it was faster. That test declares an excessive number of enums,
though, so perhaps in typical usage, and with some future optimizations, the
impact will not be so significant.
There may be other ways to solve this, such as providing a version of the macro
that does not trim strings at compile time, but only checks if they need
trimming. If some string does need trimming, that macro would fail a
static_assert and ask the user to use the slow macro.