See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89325
This bug produces massive amounts of spurious warnings and is present
in the version of g++ currently available in RHEL devtoolset-7 and devtoolset-8.
2 lines had tabs in the middle of the code, between spaces. This can
cause warnings in some tools and red markings in Git when commiting
code (tabs are to be used only as the starting characters, never after
any character).
After this commit, there are no tabs in the file at all.
These are in violation of the C++ standard. Renamed by lowercasing the
offending letters.
Affected identifiers:
- _Iterable -> _iterable
- _PutNamesInThisScopeAlso -> _putNamesInThisScopeAlso
_ _enumClassForSwitchStatements -> _enumClassForSwitchStatements
- _to_index which return value 0... size-1
(even if enums are note sequential)
- _from_index used for other way around
- _from_index_nothrow no throw version
- _from_index_unchecked returns invalid enum
in case arg>=size
Code and test cases added.
No documentation updates (my English is too poor for that)
Microsoft's incomplete constexpr implementation does not currently
allow constexpr use of constexpr functions that are defined out of line
below their point of use. The reordering in this commit is a
workaround.
While this still doesn't give MSVC constexpr support due to additional
bugs in Microsoft's implementation, maintaining the member functions in
this order makes it easier to begin each attempt to work around the
remaining compiler bugs.
By default, Better Enums will generate with an inaccessible (private or
deleted) default constructor. However, if the user defines
BETTER_ENUMS_DEFAULT_CONSTRUCTOR(Enum), the expansion of that macro
will be used instead. The macro approach was chosen because the
expansion can include access modifiers and fragments such as
"= default".
Resolves#10.
The user-supplied constant names are used to declare an internal enum
type. They end up sharing a namespace with some internal library
values. Those internal values had names not prefixed with underscores.
As a result, it was impossible to declare enum constants with these
names.
Prefixed the internal names with underscores.
VC2008 has two quirks. It generates linking errors if a copy
constructor is not explicitly defined on a Better Enum, and it has a
buggy interaction between the ternary operator and throw. This change
detects VC2008 and generates alternative code for that compiler.
Having an explicitly-defined copy constructor in a literal type appears
to cause an internal compiler error in g++4.7, and causes a spurious
compilation failure in g++4.8. For this reason, the copy constructor
generation is conditioned on the compiler.
The replacement code for the ternary operator is also generated
conditionally, because it uses an if-statement. The normal code has to
compile in a constexpr context, and so has to use the ternary operator
instead of the if-statement.
Resolves#6.
These are now only assumed in C++11 mode. long long is also assumed
only in C++11 mode for clang, which may make some programs that rely on
long long as an extension in C++98 fail with Better Enums. I will solve
that at a later date if it becomes a problem.
An alternative constant _size_constant is provided for use in C++98,
for example for declaring arrays.
Also renamed underlying_traits to integral_mapping.
Removed the function are_equal. Comparison is now done by converting
operands to their integral representation, and comparing those. Also
restored ordering of enum values along the same lines (according to
integral representation).
Before this change, in C++98 and C++11 "fast" mode, initializer
trimming was done "lazily" the first time _to_string or _names was
called. To make performance more "predictable", an object with static
storage is now used to force initializaton during program start-up,
when static object constructors are called.
The benefit of this change is very debatable. I had to give the static
object static linkage to avoid duplicate symbols, so there is a copy
now in each translation unit. I hope this does not increase code size
too much in realistic scenarios.
Lazy initialization checks are still performed and cannot be removed,
because other objects with static storage may try to use an enum from
their constructors before the enum's initialization is forced.
When compile-time stringized constant name trimming is disabled (off by
default), trimming happens "lazily" - the first time the user calls a
function such as _to_string, the function allocates space for trimmed
constant names and trims them there.
With this change, space is reserved statically in a writeable char
array, and trimming happens in that array instead.
To avoid paying the huge penalty of including iostream and string for
users that don't need those headers, and to avoid creating a second,
optional header file, I resorted to defining the operators as templates
to prevent type checking until the user tries to actually use them. The
stream types and strings are wrapped in a metafunction that depends on
the template parameter. This is basically a hack, but it seems to work.
With this change, the underlying type can be a non-integral type that
provides conversions to and from an integral type. See the test at
test/cxxtest/underlying.h for some examples - though they are more
verbose than strictly necessary, for testing needs.
Move constructors in underlying types are not supported. It has been
difficult so far to get constexpr code not to select the move
constructor, which is generally not constexpr, for various operations.
support to VC++.
The unit test is currently not being run on VC++ due to a problem with CxxTest,
Cygwin, and paths. However, the examples are being compiled and having their
output checked, and the multiple translation unit test is being run.
Running "(cd test ; ./test.py)" should now run tests only using the default
compiler, on a Unix-like system. test.py --all runs tests on the full array of
compilers that I have installed and symlinked on my development machines.
The documentation is now generated from markdown. Samples are generated from the
tutorial pages. Testing is done by a Python script which runs the tests for a
large number of compilers.
This version is not very developer-friendly - the Python scripts need ways of
limiting what compilers they try to run. If you don't have 15 compilers
installed, you won't be able to run the tests in this commit. Fix coming soon.
This patch contains several minor changes.
- Eliminated the use of a deleted constructor in C++11. C++98 private default
constructor is sufficient.
- Eliminated old namespace _enum and merged it with namespace better_enums.
- Prefixed size_t with std:: to comply with standards more strictly.
- Shortened feature control macros by deleting the word "FORCE".
Also moved make_macros.py.