我需要压缩结构以节省内存,并且得到了这样的数据结构:
enum class Foo {
F1,
F2,
F3,
FEnd,
};
struct Bar {
bool b: 1;
Foo foo : 2; // Foo has 3 elements, 2 bits can represent them
};
而且Foo
的元素仍有机会增加,所以我不想对Foo foo:2
进行硬编码并在Foo
每次添加元素时都进行更改。
[目前,我有一个解决方案:constexpr static int i = 32 - __builtin_clz(static_cast<int>(Foo::FEnd));
,但这太丑陋且无法移植。
有什么建议吗?
由于C ++标准未提及constexpr
数学库,因此解决方案是:
constexpr uint64_t bits(const uint64_t x) {
int i = 64;
uint64_t mask = 0x8000000000000000;
while (i > 0) {
if ((mask & x) != 0) return i;
i--;
mask /= 2; // do not use >>, which is a non-constexpr in standard.
}
return 1;
}
然后示例代码将如下所示:
struct Bar {
bool b: 1;
Foo foo : bits(static_cast<int>(Foo::FEnd) - 1);
};
如果使用的是GCC,则有一个内置的constexpr log2(x),那么代码将是:
struct Bar {
bool b: 1;
Foo foo : std::log2(static_cast<int>(Foo::FEnd) - 1) + 1;
};