Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Fill extern std::array fileds one by one

I have the following code

   //Block.h
    enum class BlockType : uint8_t {
    BlockType_Air = 0,
    BlockType_Default = 1,
    BlockType_Grass = 2,
    BlockCount
};

struct BlockTextureData {
    std::string top;
    std::string bottom;
    std::string left;
    std::string right;
    std::string front;
    std::string back;
};

extern std::unordered_map<BlockType, BlockTextureData*> BlockTextures;

   //Block.cpp
std::unordered_map<BlockType, BlockTextureData*> BlockTextures = {
    {BlockType::BlockType_Default, new BlockTextureData{"UV","UV","UV","UV","UV", "UV"}},
    {BlockType::BlockType_Grass, new BlockTextureData{"GrassTop","GrassBottom","GrassSide","GrassSide","GrassSide", "GrassSide"}}
};

Issue is the map is accessed thousands of times whitc causes it to rack up quite a performance cost, as its makes itself a bout 20% of the runtime of the given functions its in. I head you can use enum values as keys for arrays, so i wanted to replace std::unordered_map with std::array. But when i tried to populate the array i got error that its incomplete.

The thing is all enum values dont need a corresbonding object in BlockTexturers and can be null. So i would like to define the values one by one. Is there a way to do this ?

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

my attempt

//block.h
extern std::array<BlockTextureData*, static_cast<size_t>(BlockType::BlockCount)> BlockTextures;

//block.cpp
std::array<BlockTextureData*, static_cast<size_t>(BlockType::BlockCount)> BlockTextures[static_cast<size_t>(BlockType::BlockType_Default)] = new BlockTextureData{"UV","UV","UV","UV","UV", "UV"};

std::array<BlockTextureData*, static_cast<size_t>(BlockType::BlockCount)> BlockTextures[static_cast<size_t>(BlockType::BlockType_Grass)] = new BlockTextureData{"GrassTop","GrassBottom","GrassSide","GrassSide","GrassSide", "GrassSide"};

>Solution :

You could use a helper function:

static auto makeBlockTextures() {
    std::array<BlockTextureData*, (std::size_t)BlockType::Count> arr{};
    arr[(std::size_t)BlockType::Default] = new BlockTextureData{ /* ... */ };
    arr[(std::size_t)BlockType::Grass]   = new BlockTextureData{ /* ... */ };
    return arr;
};

std::array<BlockTextureData*, (std::size_t)BlockType::Count>
    BlockTextures = makeBlockTextures();

or an immediately invoked lambda:

std::array<BlockTextureData*, (std::size_t)BlockType::Count> BlockTextures = []()
{
    std::array<BlockTextureData*, (std::size_t)BlockType::Count> arr{};
    arr[(std::size_t)BlockType::Default] = new BlockTextureData{ /* ... */ };
    arr[(std::size_t)BlockType::Grass]   = new BlockTextureData{ /* ... */ };
    return arr;
}();
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading