Add a helper to support map semantics on a constexpr std::array
dmachaj opened this issue · comments
Our project has a variety of helpers that convert between enum values and their stringified equivalent (and back again). The mapping is fixed at compile time so this data could go into .rdata for greatest efficiency. However, most people default to using a const std::map
in the global namespace, which uses dynamic initializers to initialize the map with code at DLL load time.
It would be nice if we could have our cake and eat it too by having an adapter of some sort that uses a constexpr std::array
as the storage with some easy-to-use lookup functions layered on top to make it "map like" in usage patterns.
Example map code
enum class MyEnum
{
Foo,
Bar
};
const std::map<const std::wstring, MyEnum> c_mapping = {
{L"Foo", MyEnum::Foo},
{L"Bar", MyEnum::Bar}
};
std::wstring LookupMyEnumValue(MyEnumconst& value)
{
return c_mapping .find(value)->second;
}
Proposed new code
constexpr wil::constant_map<const std::wstring, MyEnum> c_mapping = {
{L"Foo", MyEnum::Foo},
{L"Bar", MyEnum::Bar}
};
std::wstring strValue = c_mapping.Lookup(value);
I'm sure someone has created a constexpr
friendly sorted_array
type. Combine that with std::(ranges::)lower_bound
and voilà, you have a solution. Main downside is needing a custom comparator function since you're only searching on a single member of the struct. You'll also need to deal with iterators, but you probably want a way to deal with "not found" anyway. Creating a sorted_array
type likely shouldn't be too bad, however I'm not quite sure how to handle non-movable types.
Additionally, there's got to be at least a dozen "reflection" "libraries" out there now that solve the "convert enum to/from string" problem. We also should eventually be getting real compile-time reflection in the language. Any day now...
That's all to say... this isn't really a Windows-specific issue & multiple solutions exist for it already, so I'm not quite sure it necessarily fits into WIL's "charter."
That's totally fair. I'll go ahead and close this and it can stay in the record of closed issues.