-
Notifications
You must be signed in to change notification settings - Fork 26
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
Custom string representation #20
Comments
Np :-). The thing is that probably the single biggest thing that this library achieves is avoiding repeating all the enumerator names. The enumerator name itself doesn't matter much, so usually you just pick something based on how you want it to display (for this reason I'm also a bit confused at the necessity to rename an enum value in a refactor). Once you're writing out all the enumerator strings by hand, couldn't you just write a free function(s) that wrap the to/from string methods of wise enum, and handle any special cases yourself? There's also a technical reason why this is difficult. As you may know, macro tokenization is only aware of commas and parens. That means that if you have something like So to support this feature I would start to have all these caveats. Currently, I'm very happy with the fact that I avoid any of these caveats (which people tend to hate about macros); you can use (AFAIK) any valid C++ expression for the enumerator value and it should work just fine. The closest I could imagine easily at this point is a |
Thanks for the extensive reply, that was very insightful 👍 I understand your point, and that what you have now is probably the "sweet spot" of macros. I'll use a free function layer as you suggested, it's not a big deal. And it's nice that in most cases the code can fall through to the auto-generated strings, without having to type them twice. |
Hi, I just wanted to chime in on this, as this is a use-case I am also looking at.
The reason is that we really want to have one canonical way of defining these enums. In our case we use them for values that has some hard-coded meaning towards databases. And the database strings sometimes contains characters or combinations thereof, that are not valid in c++ enums. In those cases, we want to specify the enum in c++, and simply add the overriding string representation. If we were to write these by hand, this is a PITA because we then would have to emulate the ergonomics of whatever enum library we use to avoid unpleasant surprises with difference in behaviour (e.g for wise enum, using the custom optional when compiling for c++11, std::optional for c++17, and ALL other behaviour). We could do what you suggest (which is almost what we are doing now), and then use the enum-library internally in the mapping functions instead, so that those are easy to create in the cases where the strings are legal enum names in c++. We do this currently with better-enums, and then use better-enums But all this results in a lot of boilerplate and unpleasantries compared to just being able to use the enum-library without the wrapping on top, if it had some way to customize the enum to string mapping(and back) in the few cases where its needed. If wise-enum provides this, we would probably switch from better-enums, because the overall ergonomics (with the enums actually being enums) seems better too. |
@andoks Ok, you raise good points. What would you say to declaring the enum plainly, and then having the adapt macro take optional strings for each enum? You'd have to repeat the enumerators, which is a downside (and keep the enum and adapter in sync). The problem with doing a single macro, as I mentioned before, is the fact that you have three possible arguments for each enumerator: the c++ name, the value, and the string. The latter two are both ideally optional, which I can't really deal with, and worse they're not guaranteed to be single macro tokens. So it's just very difficult to imagine what a single macro would look like. I could have a convenience macro that would allow defining enums with custom strings but not controlling the values, but inevitably someone will ask for that too. And of course, those convenience macros would all have to be multiplied by 4 (for enum/enum class, inside/outside a struct). Another reason why I like the solution of forcing a vanilla enum declaration, and then allowing custom strings in the adapter. Thoughts? |
@quicknir : for my use-case, the one related to databases and the strings only sometimes not matching what is legal c++ enum names, I have absolutely no issue with declaring it as an enum + some kind of adaptor. What I think is the most important is not the (relatively) few places we have to define the custom-stringed enums, but rather that the use (to-string, from-string) of the custom-string enums and the not-custom-string enums are identical with respect to the enum-library (wise-enum in this case) API. If there are differences in the usage API, I foresee huge pains with devs having to learn through painful bugs, that they always have to check the implementation-file for the enum they want to use every time, and check if it is custom-string or not (or automate it by using project-specific functions, but this carries somewhat the same problems, as devs might end up using the enum-API for tostring/fromstring regardless). |
Just a quick note that this would be great for us too, similar use case: Database column names, whilst keeping a consistent code style. |
Thanks for this nice software! |
Hi, thanks for this very interesting project!
Would it be possible to define a custom string for each enum value, instead of auto-generating it from the token? For example, instead of:
You could write:
(there's probably a better name than
CUSTOM
)The main advantage for my use case: Let's say you use
(GREEN, "GREEN")
and the string is persistently stored in configuration files / XML / JSON etc. Later you rename theGREEN
enum value in a refactor. This way it remains compatible with the old files because the string"GREEN"
is independent. If you want, you can keep the old string, or decide to write custom code for backwards compatibility. But the compatibility doesn't break without notice.The text was updated successfully, but these errors were encountered: