aantron / better-enums

C++ compile-time enum to string, iteration, in a single header file
http://aantron.github.io/better-enums
BSD 2-Clause "Simplified" License
1.68k stars 173 forks source link

allow custom strings #65

Open sena73 opened 6 years ago

sena73 commented 6 years ago

It is sometimes very useful to have custom string names, due to C++ limitations. Something like

BETTER_ENUM_CUSTOM_NAME(Food, uint8_t, GreenSalad, "green salad", RedTomato, "red tomato")

would help in such situation.

aantron commented 6 years ago

@sena73, we couldn't easily do this because the text in (…) is currently pasted into an ordinary enum declaration, so it has to be syntactically valid for an enum. We do that because, that way, we can support optional = 42 syntax, exactly the same as for real enums. It likely possible to do it with extra preprocessing somehow, though.

You may be able to address you need with an std::map defined right under the macro. Alternatively, if you want the map to be constexpr, consider this.

sena73 commented 6 years ago

You may be able to address you need with an std::map defined right under the macro.

Thank you. This works pretty well for me. Resulting code does not look super clean, especially for C++11, but it is better than any other know solution. Unexpected advantage is that I can define several map generators for the same enum if needed.

My problem is solved, but may be it makes sense to add this answer to documentation, before closing the issue?

aantron commented 6 years ago

Yes, we can leave it open for editing the docs. I need to restore my Better Enums dev environment before I can do that, so it might take a while to actually get the edit in :)

andoks commented 5 years ago

This feature is incredibly useful when the string definitions are out of developer control. Hyphens are not allowed in enums, and neither is starting the enum with a number. Both cases which can be fairly common when these limitations are not present for whoever defines the strings.

If I understand it correctly though, this does not replace the default to/from for strings, but makes a map which can be used explicitly? If that's true, I would like to suggest a way to replace the currently automatic to/from using a similar simple mapping function.

aantron commented 5 years ago

@andoks, what do you mean by the word this in

If I understand it correctly though, this does not replace the default to/from for strings

?

The biggest initial problem with the feature in this issue is that there isn't a practical way to implement it, given what Better Enums is trying to be, at least not one that is obvious to me right now. A major idea behind Better Enums is that everything in the "..." in BETTER_ENUM(Foo, int, ...) gets pasted, verbatim, into a C++ enum declaration, so that its behavior is predictable, and obeys, exactly, the rules of C++, which are already familiar to the library's user.

I would like to suggest a way to replace the currently automatic to/from using a similar simple mapping function.

This can be desirable, but I'd ask that you offer a specific proposal :) Including both what it would look like in terms of syntax, and also some sketch of how to implement it (because Better Enums is pretty constrained by the metaprogramming limitations of C++).

Would if offer a significant advantage over http://aantron.github.io/better-enums/tutorial/Maps.html?

andoks commented 5 years ago

@aantron

what do you mean by the word this in

I meant the make_maps functionality that you linked to. Which was great BTW.

Would if offer a significant advantage over http://aantron.github.io/better-enums/tutorial/Maps.html?

The advantage is in that the users of any enum does not need to concern themselves with the string-representation (custom through mapping, or automated by the better-enum macro), and can trust that the what they get out of the _from_string() and _to_string() is "correct" for the context (given that there is only one canonical way of representing that enum as a string that is).

Say you have a header called database_codes.h, which defines all of your hard-coded strings from the database in different enums. You can declare that all those codes are to be _from_string()ed and _to_string()'ed when reading/writing to the database. However if at some point someone introduces any symbol that make the enum not a valid enum-name in c++ (or say these codes have been living for a while before you discover better-enums as a great tool for automating this job), you have to deploy work-arounds for those enums specifically.

Being able to specify the tostring/fromstring mapping, overriding the existing one, would make that difference in API go away for the users of the enum. The producer of the enum of course has to do some extra work for specifying the enum to/from string, but that is relatively minor.

aantron commented 5 years ago

That does seem like a worthwhile advantage.