0 ~ 255 の値に対して、事前計算されたビット カウント値 (数字の 1 ビットのカウント) を含む LUT を作成する必要があるとします。
int CB_LUT[256] = {0, 1, 1, 2, ... 7, 8};
ハードコーディングされた値を使用したくない場合は、適切なテンプレート ソリューションを使用できます。32 ビット整数で設定されたビット数をカウントするには?
template <int BITS>
int CountBits(int val)
{
return (val & 0x1) + CountBits<BITS-1>(val >> 1);
}
template<>
int CountBits<1>(int val)
{
return val & 0x1;
}
int CB_LUT[256] = {CountBits<8>(0), CountBits<8>(1) ... CountBits<8>(255)};
この配列は、コンパイル時に完全に計算されます。長いリストを回避し、ある種のテンプレートまたはマクロを使用してそのような配列を生成する方法はありますか (申し訳ありません!)、次のようなものです。
Generate(CB_LUT, 0, 255); // array declaration
...
cout << CB_LUT[255]; // should print 8
注意事項. この質問は、数値の 1 ビットを数えることに関するものではなく、例として使用されています。外部コード ジェネレーターを使用せずに、このような配列をコード内で完全に生成したいと考えています。コンパイル時に配列を生成する必要があります。
編集します。コンパイラの制限を克服するために、Bartek Banachewicz のコードに基づいて、次の解決策を見つけました。
#define MACRO(z,n,text) CountBits<8>(n)
int CB_LUT[] = {
BOOST_PP_ENUM(128, MACRO, _)
};
#undef MACRO
#define MACRO(z,n,text) CountBits<8>(n+128)
int CB_LUT2[] = {
BOOST_PP_ENUM(128, MACRO, _)
};
#undef MACRO
for(int i = 0; i < 256; ++i) // use only CB_LUT
{
cout << CB_LUT[i] << endl;
}
私はこれがおそらくUBであることを知っています...