Выглядит примерно так:
#define MY_FRUITS (apples)(oranges)(pears)Работать с этими данными можно, например, так:
BOOST_PP_SEQ_ENUM(MY_FRUITS)Эта конструкция раскроется в список, разделенный запятыми:
apples, oranges, pearsБолее сложная конструкция:
Получаем:#define MY_DECLARE_FRUIT(r, data, elem) \
data elem = 0;
/* (1) */
BOOST_PP_SEQ_FOR_EACH(MY_DECLARE_FRUIT, int, MY_FRUITS)
#define MY_FRUIT_ARG(s, data, elem) \
data elem
/* (2) */
void TakeAllFruits(
BOOST_PP_SEQ_ENUM(
BOOST_PP_SEQ_TRANSFORM(
MY_FRUIT_ARG,
int,
MY_FRUITS
)
)
);
/* (3) */
TakeAllFruits(BOOST_PP_SEQ_ENUM(MY_FRUITS));
Практика показывает, что большей гибкостью обладает подход, при котором все генерирующие код конструкции полностью заворачиваются в макросы. То есть генерацию заголовка функции TakeAllFruits в пункте (2) лучше оформить таким образом:/* (1) */
int apples = 0;
int oranges = 0;
int pears = 0;
/* (2) */
void TakeAllFruits(
int apples,
int oranges,
int pears
);
/* (3) */
TakeAllFruits(apples, oranges, pears);
Последовательности можно делать вложенными. Это позволяет, например, реализовать на препроцессоре эквивалент «записей» (records).#define MY_TAKE_ALL_FRUITS(fruits) \
void TakeAllFruits( \
BOOST_PP_SEQ_ENUM( \
BOOST_PP_SEQ_TRANSFORM( \
MY_FRUIT_ARG, \
int, \
fruits \
) \
) \
);
MY_TAKE_ALL_FRUITS(MY_FRUITS)
Возьмем для примера условную структуру данных, описывающую геометрические фигуры:
Фигура:При помощи последовательностей этот набор данных можно выразить примерно таким образом:
- Способ рисования
- Список свойств
Да, кстати, совет общего характера: при написании многострочных макросов не забывайте следить за тем, чтобы конкатенирующий слэш '\' был последним символом в строке. Если после него окажется любой символ кроме перевода строки (даже пробел), следующая строка уже не будет считаться частью макроса. Хорошо если ваш редактор обращает внимание на этот факт при подсветке синтаксиса. Если же нет, включайте отображение пробельных символов когда пишете макросы.#define MY_TRIANGLE (0)
#define MY_SQUARE (1)
#define MY_QUADRANGLE (2)
#define MY_CIRCLE (3)
#define MY_SHAPES \
( \
(Triangle)(MY_TRIANGLE)(Polygon) \
( \
((Point)(vertex1)) \
((Point)(vertex2)) \
((Point)(vertex3)) \
) \
) \
( \
(Square)(MY_SQUARE)(Isogon) \
( \
((Point)(center)) \
((float)(radius)) \
) \
) \
( \
(Quadrangle)(MY_QUADRANGLE)(Polygon) \
( \
((Point)(vertex1)) \
((Point)(vertex2)) \
((Point)(vertex3)) \
((Point)(vertex4)) \
) \
) \
( \
(Circle)(MY_CIRCLE)(Circle) \
( \
((Point)(center)) \
((float)(radius)) \
) \
)