шаблоны — метапрограммирование для оптимизации алгоритма хранения / времени выполнения, переполнение стека

Я хотел бы обобщить побитовые операторы в C ++, не думая, что базовая структура является массивом.

В качестве примера … если я хочу представить 86 бит, я бы использовал структуру структуры / класс, например:

typedef struct {
uint64_t x[1];
uint16_t y[1];
uint8_t z[1];
} sampleStruct;

Вместо этого, если бы я хотел выделить 160 бит, я бы использовал такую ​​структуру:

typedef struct {
uint64_t x[2];
uint32_t y[1];
} sampleStruct;

Я предполагаю, что тривиальное, но не оптимальное решение для хранилища состоит в том, чтобы предположить, что все порции одинаковы и выделить минимум этих значений. он охватывает размер, который я внедряю, однако даже из-за физических упражнений я предпочитаю способ, которым я выставляюсь.

Для меня ясно, что я должен использовать метапрограммирование для решения проблемы, поэтому я должен правильно определить

template <int I>
typedef sampleStruct {
//something
}

Однако я не большой специалист по метапрограммированию шаблонов в C ++, поэтому я хотел бы понять, как лучше всего реализовать различный тип выборки структуры I. Я знаю, как выбрать наилучшее «покрытие» для моей длины. быть чем-то вроде:

N64 = I/64;
RemN = I%64;
if(0 < RemN <= 8) {
add uint8_t var;
} else if (8 < RemN <= 16) {
add uint16_t var;
} else if (16 < RemN <= 24) {
add uint16_t var;
add uint8_t var;
} else {
//Similarly handle the other cases from 24 < RemN < 64
}

Что я могу сделать, чтобы достичь того, что я хочу сделать?

Я также предполагаю, что правильное размещение фрагментов позволит достичь немного лучшей производительности по сравнению с другими возможными реализациями.

Надеюсь, это достаточно ясно …
(Предположим, C ++ 11 или более поздние версии).

5

Решение

Это возможно, но при этом достаточно много печатать. Проблема состоит в том, что C ++ не обеспечивает способ метапрограммического пропуска элемента данных (см., Например, Условное включение / исключение членов данных внутри шаблонов классов) поэтому вы должны специализироваться на его наличии или отсутствии:

template<int N64, bool P32, bool P16, bool P8>
struct sampleStructImpl;

template<int I>
using sampleStruct = sampleStructImpl<I/64, (I%64 >= 32), (I%32 >= 16), (I%16 >= 8)>;

Различные частичные специализации (всего 8) будут выглядеть следующим образом:

template<int N64>
struct sampleStructImpl<N64, true, true, true>
{
std::uint64_t x[N64];
std::uint32_t y;
std::uint16_t z;
std::uint8_t w;
};

template<int N64>
struct sampleStructImpl<N64, true, true, false>
{
std::uint64_t x[N64];
std::uint32_t y;
std::uint16_t z;
// omit std::uint8_t w;
};

// 6 more partial specializations...

Кроме того, поскольку массивы нулевой длины недопустимы, если вы хотите иметь возможность разрешать значения I менее чем 64, вам придется специализироваться на N64 быть нулем:

template<>
struct sampleStructImpl<0, true, true, true>
{
// omit std::uint64_t x[0];
std::uint32_t y;
std::uint16_t z;
std::uint8_t w;
};

// 7 more specializations...

Было бы гораздо проще использовать std::array<std::uint8_t, (I + 7) / 8>возможно с alignas модификатор для 64-битного выравнивания.

0

Другие решения

Не было бы проще использовать только массив uint8_t, например:

template <int I>
struct sampleStruct {
std::uint8_t v[(I % 8)? (I / 8) + 1 : (I / 8)];
};

Как вы упомянули, я предполагаю, что у вас нет доступа к отдельным членам x,y,z(из вопроса не ясно, как бы вы получили доступ к базовым битам ..)

Можно также делать то, что вы хотите, но вы должны использовать наследование следующим образом:

template <int I>
struct largeBlock {
std::uint64_t x[I];
};
template <>
struct largeBlock<0> {
};

template <int I>
struct mediumBlock {
std::uint16_t y[I];
};
template <>
struct mediumBlock<0> {
};

template <int I>
struct smallBlock {
std::uint8_t z[(I / 8) + ((I % 8) ? 1 : 0) ];
};
template <>
struct smallBlock<0> {
};

template <int I>
struct sampleStruct : largeBlock<I / 64>, mediumBlock<(I % 64) / 16>, smallBlock<(I % 16)> {

};

Теперь ваши операции должны быть реализованы в терминах обращений к базовым объектам …

0

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector