Finally, once this is further refined & tweaked, it may be worthy of a write-up or even presentation to the boost project or some such (I hope I'm not in fantasy land here ).
Not a bad idea, we might want to check out the competition first
I did google about a bit before deciding this was a worthy pursuit, and didn't like much of what I found, but I haven't checked the Boost vault.
I've made some further refinements, a default constructor was lacking, I'm initialising to COUNT, but I've kind of given COUNT a double meaning by using it as an 'invalid' marker, perhaps we should automagically add INVALID=-1 as well?
The casting problem is not a problem anymore, I just needed to think in a more C++ way, just a few lines of code did the trick,
template<typename E>
E enum_cast(unsigned i) {
return i < E::COUNT ? (E::Enum)i : E::COUNT;
}
Which maintains type safety and allows for unsafe conversions in a safe manner
Fruit f;
//f = Vegetable::PEA; // error, incompatible types
f = enum_cast<Fruit>(Vegetable::PEA); // ok, f == Fruit::PEAR
printf("Fruit f = %s\n", FruitNames[f]);
//f = 3; // error, incompatible types
f = enum_cast<Fruit>(3); // Ok, f == Fruit::PEACH
printf("Fruit f = %s\n", FruitNames[f]);
f = enum_cast<Fruit>(7); // Ok, but f == Fruit::COUNT because 7 >= COUNT
I also decided to explicitly have or not have the EnumNames attached, the 'wrapped' enum I'm calling WRAPPED_ENUM (for now, atleast
), which can be used if you don't want string support, and I've revived STRINGY_ENUM as,
#define STRINGY_ENUM(Name,...) \
WRAPPED_ENUM(Name,__VA_ARGS__) \
STRINGY_ENUM_NAMES(Name, Name::COUNT, __VA_ARGS__);
EnumNames is now templated on the enum object, so the usage is much nicer,
Fruit f = FruitNames.match("pear"); We're not using many for matching flags from XML, so the amount that need to be STRINGY isn't great, and for debugging, we can just make all WRAPPED enums STRINGY as well.
So, a couple of outstanding issues I can think of:
1. add INVALID to all enums ?
2. capitalisation and spacing policy for displayed names ?
NB: haven't committed any changes yet, I have the NodePool object in pieces, hopefully will have it back together soon, and will commit then