计算位以表示编译时的枚举

问题描述 投票:0回答:1

我需要压缩结构以节省内存,并且得到了这样的数据结构:

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++ enums bit-fields
1个回答
0
投票

由于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;
};
© www.soinside.com 2019 - 2024. All rights reserved.