Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Summary
SUMMARY: Infrastructure "Overhaul of enum <-> string conversion code"
Purpose of change
The previous approach to conversion between enum and string values had two function templates which had to be specialized for every enum (
enum_to_string
andstring_to_enum
).Typically, they were implemented by having a global static map from strings to enum values which was used for lookup in one direction. Conversion in the other direction (enum -> string) was usually not implemented, but when it was it used a slow linear search through the map.
The problems I see with this approach are primarily:
enum_to_string
should not be slow, but we don't want to have a separate map or array defined for every enum to make it fast.Describe the solution
Change this to a new approach where only
enum_to_string
needs to be specialized, and string_to_enum is automatically synthesized from it.The advantages of this approach are:
enum_to_string
should be much more efficient.enum_to_string
can be implemented via a switch statement, which means the compiler will automatically let you know to update it when a new enum value is added to any enum (via the warning about unhandled enum values).string_to_enum
. Consistency between the conversions in each direction happens automatically.The disadvantages include:
string_to_enum
contains aconst static
map initialized on first use, so there will be a check that it's initialized on every call. But this should be cheap compared to anunordered_map
lookup.To implement this I took advantage of the
enum_traits
originally added forenum_bitset
. Every enum supporting such conversion now needs a 'last' member and anenum_traits
specialization for the code to know which member this is (many of them already had such members). This new 'last' member needs to be handled somehow in any switch over the enum.So, as a happy side-effect, all these enums will now work with
enum_bitset
without further changes.I used astyle markup around the big switch statements to get one case per line; I find this much easier to read and see at a glance that the values match in a reasonable way.
Describe alternatives you've considered
Many things could be done differently:
Additional context
I was inspired to do this by working on #32891 where I'm adding two new enum types that will need fast conversion in both directions.
I was hoping this change would be an overall reduction in lines of code. Alas, it is not.