C++ 使用位集访问向量索引

C++ 使用位集访问向量索引,c++,C++,我正在尝试编写我自己的实体组件系统,我想要一种快速(在可能的情况下为常数时间)但又能节省内存的方式来访问实体组件 使用全局映射(std::unordered_map),将每个实体映射到包含其组件的排序向量: Key Value --- ----- EntityA -> Sorted vector of components EntityB -> Sorted vector of components [..] -> [..] 每个实体都有一

我正在尝试编写我自己的实体组件系统,我想要一种快速(在可能的情况下为常数时间)但又能节省内存的方式来访问实体组件

使用全局映射(
std::unordered_map
),将每个实体映射到包含其组件的排序向量:

Key        Value
---        -----
EntityA -> Sorted vector of components 
EntityB -> Sorted vector of components
[..]    -> [..]
每个实体都有一个位集,指示该实体具有哪些组件,即:

|C0 |C1 |C2 |C3 |C4 |C5
 0   0   1   0   1   1

and on the map:
Key        Value
---        -----
EntityA -> [C2,C4,C5]
由于很少添加组件,我可以承担排序插入的成本,但我绝对希望快速访问

现在我从位集中知道C4是第二个元素集(从左边开始计数),所以它应该在第二个向量索引处

如何将其写入一个方法中,该方法将返回给定组件类型ID的实体的组件? 例如


假设我们的成员是:

std::bitset<6> bits;
std::vector<Component> comps;

使用掩码是否比简单右移然后计数位更快@ᴘᴀɴᴀʏɪᴏᴛɪs我相信它在某些情况下是存在的-您必须根据您的用例对其进行计时,并根据可读性对其进行评级,等等。
std::bitset<6> bits;
std::vector<Component> comps;
Component* getComponent(int id) {
    // we need to find how many bits are set for ids < id
    // first, make sure this one is set:
    if (!bits[id]) return nullptr;

    // then, let's count
    int idx = 0;
    for (int i = 0; i < id; ++i) {
        if (bits[i]) ++idx;
    }

    // now, just return the right pointer
    return &comps[idx];
}
Component* getComponent(int id) {
    if (!bits[id]) return nullptr;

    // flip id and get a mask
    // if we have C0 .. C5, and we pass in 4
    // we want the mask 0x111100
    unsigned long mask = (1 << (bits.size() - id)) - 1;
    mask = ~mask;

    // apply the mask to the bitset
    // so from 0x001011, we get 0x001000
    unsigned long new_bits = bits.to_ulong() & mask;

    // count how many bits are set there
    unsigned int popcnt = __builtin_popcount(new_bits);

    // and there we have it
    return &comps[popcnt];
}