magic_enum
magic_enum copied to clipboard
constexpr enum map
The C++17 standard does not allow to use allocators, and dynamic containers (like std::unordered_map, std::map) in constexpr time.
It is a handy feature, if magic_enum
would offer an enum_map<EnumType, T>
, which is implemented as std::array<T, enum_count<EnumType>>
or std::array<optional<T>, enum_count<EnumType>>
with a typesafe O(1)
complexity operator[](EnumType)
, at(EnumType)
functions , and stl-like constexpr interface.
Consider EnumMap
/EnumSet
from https://github.com/teslamotors/fixed-containers
Uses magic_enum
under the hood and is fully constexpr
.
Thanks @alexkaratarakis , but I have only C++17 std available compiler, fixed-containers use C++20
I think these containers not fits to the magic_enum.hpp
header file.
Probably it need to put to an another header file, like magic_enum_containers.hpp
.
But then the library looses the "only one header" property. What do you think @Neargye ?
Are we missing something the current api? Do we need containers?
struct enum_map<EnumType, T> {
optional<T> values[enum_cout<EnumType>()];
auto operator[](E v)
if (const auto index = enum_index<EnumType>(v); index.has_value()) {
return values[*index];
}
return nullopt;
}
Something like that, but with constexpr functions, and stl-like api (in C++17).
https://github.com/Neargye/magic_enum/compare/master...schaumb:containers?expand=1
I started my own solution.
Currently I only created constexpr magic_enum::containers::array<E, V>
and magic_enum::containers::bitset<E>
(std::bitset is not constexpr in latest standard)
bitset
can be useful to transform not flag enums to 'flagged'.
I think other array
constructions (which contains enums as parameter) can be define.
FYI, hope bitset will be constexpr soon
Could you please make a PR, so it will be more convenient to check?
today's conclusion: containers::map<E, mapped_type>::insert
can be constexpr in c++17 only if any of the following condition is met to mapped_type
:
-
trivially_assignable
(union) -
default_constructible
(array) - has constructor which can be called with default constructed arguments (array)
- explicitly grant an object as "default/invalid" element (array)
note0: (union) procedure will be the closest to std::map
note1: (array) procedure will create mapped_type
objects for all enum value at construction time.
note2: std::map::operator[]
and containers::map<E, mapped_type>::operator[]
are requires mapped_type
to be default_constructible
You might want to have a look at https://github.com/Julien-Blanc-tgcm/indexed_array . I just added magic_enum support, and i think it provides what you want (unless you need iteration on both the key and the value, which is not yet provided)
Thanks @Julien-Blanc-tgcm , It is a nice library.
Why is the iterators and the modification functions are not constexpr? What if Value is not default constructible?
I started to implement not only enum_array, but enum_map, enum_bitset, enum_set.
Thanks for spotting the missing constexpr. It may be better to discuss this in indexed_array issue tracker, though. As for non default constructible values this is not an issue if they are provided at initialization (just like a plain std::array).
Closed by https://github.com/Neargye/magic_enum/pull/187