microsoft / wil

Windows Implementation Library

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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.