Возможны ли двумерные последовательности с помощью Boost.Preprocessor?

Последовательности Boost.PP ограничены 256 элементами. Чтобы обойти это, я хочу использовать двумерные последовательности или последовательность последовательностей, которые будут определены следующим образом:

((0)(1)(2)...(255))((256)(257))

Теперь, чтобы предоставить BOOST_PP_SEQ_FOR-подобный алгоритм, я хочу вложить два из них следующим образом:

//Inner loop
#define ELEM_ID_OP(_, func, elem) func(elem)
#define FOR_ELEM(func, seq) \
    BOOST_PP_SEQ_FOR_EACH(ELEM_ID_OP, func, seq)

//Outer loop
#define SEQ_ID_OP(_, func, seq) FOR_ELEM(func, seq) 
#define FOR_SEQ(func, multiseq) \
    BOOST_PP_SEQ_FOR_EACH(SEQ_ID_OP, func, multiseq)

//Testing function
#define MYFUNC(arg) \
    const int arg = 0;

FOR_ELEM(MYFUNC, (Zero)(One)(Two)) //works like a charm

FOR_SEQ(MYFUNC, ((zero)(one)(two))) //doesn't :(

На втором я получаю несколько ошибок о необъявленных идентификаторах:

ошибка C2065: «ELEM_ID_OP»: необъявленный идентификатор
ошибка C2065: «MYFUNC»: необъявленный идентификатор
ошибка C2065: «ноль»: необъявленный идентификатор
ошибка C2065: «один»: необъявленный идентификатор
ошибка C2065 : 'two' : необъявленный идентификатор

Означает ли это, что максимальная глубина рекурсии моего компилятора достигнута, поэтому макросы ELEM_ID_OP и MYFUNC больше не раскрываются? Или в Boost.PP есть деталь реализации, которая мешает этому работать? Есть ли обходной путь для этого?

Я использую VC++2013, если это поможет.


person iFreilicht    schedule 04.11.2014    source источник


Ответы (1)


Boost.Preprocessor не может выполнять вложенные SEQ_FOR_EACH. Если бы вы использовали приличный препроцессор, вы могли бы использовать Chaos, который может выполнять такое произвольное вложение (хотя это не нужно только для SEQ_FOR_EACH, поскольку длина последовательности в Chaos не ограничена).

Для чего-то такого простого вы могли бы сделать это напрямую с помощью VC++ с помощью чего-то вроде

#define CAT(a, ...) PRIMITIVE_CAT(a, __VA_ARGS__)
#define PRIMITIVE_CAT(a, ...) a ## __VA_ARGS__

#define A(id, value) const int id = value; B
#define B(id, value) const int id = value; A
#define A0
#define B0

#define C(bseq) CAT(A bseq, 0)

C(
    (zero, 0)
    (one, 1)
    (two, 2)
)

#undef A
#undef B
#undef A0
#undef B0
#undef C
person Paul Mensonides    schedule 05.11.2014
comment
Представьте себе, что я сталкиваюсь с трудностями определения достаточного количества макросов для обработки 256 записей в последовательности, сможет ли представленный вами метод действительно обрабатывать вложенные последовательности? - person iFreilicht; 05.11.2014
comment
@iFreilicht Вышеупомянутое будет работать с последовательностями произвольной длины. - person Paul Mensonides; 05.11.2014