How to implement a flat map using arrays when keys are known at compile time. Imagine I know my keys:
enum class Asset
{
FONT,
TEXTURE
};
struct AssetContainer
{
};
Hence I could do:
struct STATIC_DATA
{
inline static std::unordered_map<Asset, std::atomic<std::shared_ptr<const AssetContainer>>> ASSET_CACHE = {
{Asset::FONT, nullptr},
{Asset::TEXTURE, nullptr}
};
it looks like since I know my keys and size I can optimize this by writing a const size map using arrays as:
template<class Key, class Value, size_t Size>
struct static_map
{
using container = std::array<std::pair<Key, Value>, Size>;
}
struct STATIC_DATA
{
inline static static_map<Asset, std::atomic<std::shared_ptr<const AssetContainer>>> ASSET_CACHE = {
{Asset::FONT, nullptr},
{Asset::TEXTURE, nullptr}
};
};
The compiler will not optimize an unordered map into an array.
template<class Enum, class Value, std::size_t Count>
struct EnumMap:std::array<Value,Count> {
// Get the array out (base class):
constexpr std::array<Value, Count>& Array() { return *this; }
constexpr std::array<Value, Count> const& Array() const { return *this; }
// lookup in base (array):
constexpr Value& operator[]( Enum e ) {
return Array()[ static_cast<std::underlying_type_t<Enum>>(e) ];
}
// use non-const version and cast back to const:
constexpr Value const& operator[]( Enum e ) const {
return const_cast<Value const&>( const_cast<EnumMap&>(*this)[e] );
}
// Build from key-value pairs:
constexpr EnumMap( std::initializer_list<std::pair<Enum const, Value const>> il ) {
for (auto const&(key, value):il)
(*this)[key] = value;
}
};
that should do it reasonably well. It does needlessly default construct the values.
EnumMap<Asset, std::atomic<std::shared_ptr<const AssetContainer>>, 2> foo = {
{Asset::FONT, nullptr},
{Asset::TEXTURE, nullptr}
};