Вы можете использовать BOOST_PP_TUPLE_ENUM
для получения расширения элементов кортежа, разделенных запятыми. Затем вы можете использовать #__VA_ARGS__
для создания результирующего списка. Посмотрите вживую:
#define STRINGIZE_ALL_I(...) #__VA_ARGS__
#define STRINGIZE_ALL(...) STRINGIZE_ALL_I(__VA_ARGS__)
#define MAKE_STRING(tuple) STRINGIZE_ALL(Foo<BOOST_PP_TUPLE_ENUM(tuple)>)
// "Foo<float, string, int, bool>"
MAKE_STRING((float, string, int, bool))
STRINGIZE_ALL_I
существует по той же причине, по которой у вас есть дополнительный слой в STRINGIZE
и CONCAT
— для оценки макросов перед строкой. В этом случае вы получите строку, содержащую BOOST_PP_TUPLE_ENUM((…))
, если вы пренебрегли двумя слоями.
Обратите внимание, что STRINGIZE_ALL
вызывается со списком аргументов Foo<float
, string
, int
, bool>
. Это четыре аргумента, а не один.
Если вариативные макросы недоступны (например, C++98), вы можете воспользоваться тем фактом, что компилятор "abc" "def"
превратит в "abcdef"
. Посмотрите вживую:
#define STRINGIZE_ALL_MACRO(s, state, x) state "," BOOST_PP_STRINGIZE(x)
#define STRINGIZE_ALL(seq) \
BOOST_PP_SEQ_FOLD_LEFT( \
STRINGIZE_ALL_MACRO, \
BOOST_PP_STRINGIZE(BOOST_PP_SEQ_HEAD(seq)), \
BOOST_PP_SEQ_TAIL(seq) \
)
#define MAKE_STRING(size, tuple) \
STRINGIZE_ALL( \
BOOST_PP_TUPLE_TO_SEQ( \
size, \
(Foo<BOOST_PP_TUPLE_ENUM(size, tuple)>) \
) \
)
// "Foo<float" "," "string" "," "int" "," "bool>"
MAKE_STRING(4, (float, string, int, bool))
Для этой версии ваш автоматически сгенерированный кортеж также должен генерировать размер. Вполне возможно создать кортеж (size, (elems))
, который можно использовать с этим макросом.
person
chris
schedule
24.01.2016