Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Debugger friendly? Inheritance? #66

Open
rosetter opened this issue Oct 3, 2018 · 3 comments
Open

Debugger friendly? Inheritance? #66

rosetter opened this issue Oct 3, 2018 · 3 comments
Milestone

Comments

@rosetter
Copy link

rosetter commented Oct 3, 2018

Hi.. fantastic work! Very impressive. :)

Just a couple of unsolicited thoughts:

  1. 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. :(

  1. 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!

@aantron
Copy link
Owner

aantron commented Oct 3, 2018

@rosetter IIRC it's possible to derive a struct from one of these enums, which will then allow you to add methods.

For #2, is your debugger interpreting enum integral values and turning them back into strings?

@rosetter
Copy link
Author

rosetter commented Oct 3, 2018

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:

  1. I changed the type of _value to _enum, not _underlying to solve problem 2. Which may break older compilers.
  2. 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! ;)

@aantron
Copy link
Owner

aantron commented Oct 4, 2018

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 :/

@aantron aantron added this to the 0.11.3 milestone Aug 17, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants