Я отвечу сам. Есть на самом деле «простой» способ решения вышеуказанной задачи в препроцессоре. Библиотека boost предлагает инструменты для работы примерно на препроцессоре, как на обычных языках. У них есть пакет под названием препроцессор, входящий в состав пакета поддержки . Прочитайте документы , вы можете скачать его здесь , это часть основного пакета.
Основная функция, котораяПомочь в решении вышеуказанной задачи была идея переслать кортеж массивов в конструкции, известные нам из функционального программирования. На самом деле это BOOST_PP_SEQ_FOR_EACH(macro, data, seq)
. Еще одна особенность, которая помогла решить задачу, была эта реализация парней для создания двойных скобок вокруг каждого элемента.
Как идея, она будет работать следующим образом. У меня есть приведенный выше список кортежей:
#define frame_composition (begin_byte(0), begin_bit(0), int8_t, speed)\
(begin_byte(1), begin_bit(4), int16_t, direction)\
У меня есть некоторая последовательность действий, потому что я хочу иметь серийный первый и десериальный второй:
#define COMPOSE_FRAME(seq) \
ADD_SERIAL(seq) \
ADD_DESERIAL(seq)
Теперь содержимое каждогодобавить категорию:
#define ADD_SERIAL(seq) \
BOOST_PP_SEQ_FOR_EACH(ADD_SERIAL_ELEM, ~, GLK_PP_SEQ_DOUBLE_PARENS(seq))
#define ADD_DESERIAL(seq) \
BOOST_PP_SEQ_FOR_EACH(ADD_DESERIAL_ELEM, ~, GLK_PP_SEQ_DOUBLE_PARENS(seq)) \
Круто, мы перенаправили один и тот же список кортежей различным конструкциям, чтобы выполнить несколько разных алгоритмов. Теперь содержимое X_ELEM определяет:
#define ADD_SERIAL_ELEM(seq) \
outgoing_buffer[BOOST_PP_TUPLE_ELEM( 0, elem)] = (uint8_t) BOOST_PP_TUPLE_ELEM( 3, elem);
#define ADD_DESERIAL_ELEM(seq) \
BOOST_PP_TUPLE_ELEM(3,elem) = (BOOST_PP_TUPLE_ELEM(2,elem)) incoming_buffer[BOOST_PP_TUPLE_ELEM(0,elem)];
И, если вам нужно, вы можете различать различные варианты использования в элементе "функции" с помощью
BOOST_PP_IF(cond, t, f)
Для выполнения различных действий, например, над объектоми простые переменные
Это в настоящее время полное решение, но чтобы увидеть идею и то, что можно создать очень переносимый каркас простого генератора сообщений из cpp.