Rework some recent changes to the ENUM_CLASS() macro so that
all of the construction of enumerator-to-name string mapping
data structures is again performed at compilation time.
Details
Diff Detail
Event Timeline
Consider this program:
#include "enum_class.h" #include <iostream> ENUM_CLASS(RelationalOperator, LT, LE, EQ, NE, GE, GT) int main() { std::cout << EnumToString(RelationalOperator::LT) << std::endl; std::cout << EnumToString(RelationalOperator::LE) << std::endl; std::cout << EnumToString(RelationalOperator::EQ) << std::endl; std::cout << EnumToString(RelationalOperator::NE) << std::endl; std::cout << EnumToString(RelationalOperator::GE) << std::endl; std::cout << EnumToString(RelationalOperator::GT) << std::endl; return 0; }
Then compile it gcc 9.3.0
g++ flang_main.cpp -std=c++17 -g -O2 -fno-inline gdb a.out b enum_class.h:43 r Breakpoint 1, Fortran::common::EnumNames<6ul> (p=0x555555555648 "LT, LE, EQ, NE, GE, GT") at enum_class.h:43 43 for (; *p; ++p) {
Is this expected?
Convert return type to std::string_view, which is more compatible with constexpr than std::string.
Adjust a few call sites where this made a difference.
What happens if I have 2 ENUM_CLASS? You did not namespace Enum2String. There are no tests.
This is not a new feature, just a rework of a recent update to it. It should work as it always has.
Multiple instances of ENUM_CLASS in the same scope are distinguished by the name of the ENUM_CLASS.
EnumToString will be defined in the namespace and/or class in which the reference to the ENUM_CLASS macro appears.
Agreed. But you could still end up with two EnumToString in the same *context*. The only difference is the type of the parameter.
ENUM_CLASS(RelationalOperator, LT, LE, EQ, NE, GE, GT); ENUM_CLASS(RelationalOperator2, LT, LE, EQ, NE, GE, GT);
In that case, the difference in the parameter types is sufficient to distinguish the two functions by the usual C++ function overloading rules.
#include "enum-class.h" #include <iostream> ENUM_CLASS(RelationalOperator, LT, LE, EQ, NE, GE, GT) ENUM_CLASS(RelationalOperator2, LT, LE, EQ, NE, GE, GT) int main() { std::cout << EnumToString(RelationalOperator::LT) << std::endl; std::cout << EnumToString(RelationalOperator2::LT) << std::endl; }
LT LT
Why do you say "Restore compile time code" in the review title? EnumToString never was compite-ime until now.
I mean that the construction of the tables used by EnumToString() should now take place at compilation time rather than needing execution-time allocation and initialization.