Допустим, мне нужно создать LUT, содержащую предварительно вычисленные значения счетчика битов (счетчик 1 бит в числе) для значений 0...255:
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 бит в числе, он используется только в качестве примера. Я хочу сгенерировать такой массив полностью в коде, без использования внешних генераторов кода. Массив должен быть сгенерирован во время компиляции.
Изменить. Чтобы преодолеть ограничения компилятора, я нашел следующее решение, основанное на коде Бартека Банашевича:
#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;
}
Я знаю, что это, возможно, УБ...