Debugger friendly? Inheritance?
rosetter opened this issue · comments
Hi.. fantastic work! Very impressive. :)
Just a couple of unsolicited thoughts:
- I stumbled onto this project looking for a way to add methods to enums. So for example I'd like to be able to say:
enum Fruit { Apple, Orange };
Fruit f = Orange;
if (f.isRed()) { ... }
It would be wonderful if I could do something like:
struct Fruit {
BETTER_ENUM_BODY(Fruit, uint8_t, Apple, Orange)
bool isRed() const { return _value == Apple; }
}
Looking briefly at the code makes me think this would be difficult. :(
- The underlying storage seems to be not an enum but an integer type. So when I inspect an instance in a debugger I get an integer instead of a nice, readable string. To me this is best reason to use an enum in the first place, so it's a deal breaker.
I think I'll play around with modifying your earlier, much simpler version on CodeProject. :)
Again, great work!
Subclassing was my first thought, but I'd need to repeat the constructors and conversion operator in each derived class, which is unappealing. Also _value is then declared in the base class, not the user-facing class, which some debuggers hide with an extra level of hierarchy.
The debugger shows an integral value for the _value member in my example above because it is defined as _underlying (uint8_t), not _enum.
FWIW, I ended up modifying your simpler CodeProject version:
- I changed the type of _value to _enum, not _underlying to solve problem 2. Which may break older compilers.
- I created a second "ENUM_WITH_EXTENSION" macro that takes an "Extension" parameter. The enum class then derives from Extension so I can use the CRTP to extend the enum.
So now I can say:
template <typename T>
struct FruitExtension : public Crtp<T>
{
bool isRed() const { return this->asT() == T::Apple; }
};
ENUM_WITH_EXTENSION(Fruit, uint8_t, FruitExtension, Apple, Orange)
Where Crtp is defined elsewhere as:
template <typename T>
struct Crtp
{
constexpr T& asT() { return static_cast<T&>(*this); }
constexpr T const& asT() const { return static_cast<T const&>(*this); }
};
This makes my original desired syntax possible.. whew.
This has been a fun vacation in Meta-Uber-Land, but now it's time to get back to work! ;)
Great, I'm glad this worked. We may be able to define _value
as the enum type once we finally drop support for C++98. I want to do this, but I haven't had the time to edit enum.h
lately :/