Reputation: 747
I am beginner in using boost preprocessor. I want to use this library to generate a name from a tuple, for example I have a tuple like this (float, string, int, bool)
and I want to construct something like this "Foo<float, string, int, bool>"
. I thought that it must be easy by using BOOST_PP_STRINGIZE
, BOOST_PP_CAT
and BOOST_PP_REPEAT
but I unfortunately could not find a way to generate the string I wanted.
Please give me a suggestion about creating this string. Foo
is a class name and tuple is generated automatically during preprocess.
Upvotes: 1
Views: 1649
Reputation: 61930
You can use BOOST_PP_TUPLE_ENUM
to get a comma-separated expansion of the tuple elements. You can then use #__VA_ARGS__
to stringize the resulting list. See it live:
#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
exists for the same reason you have an extra layer in STRINGIZE
and CONCAT
- to evaluate macros before stringizing. In this case, you would get a string containing BOOST_PP_TUPLE_ENUM((…))
if you neglected to have two layers.
Note that STRINGIZE_ALL
is called with the argument list Foo<float
, string
, int
, bool>
. That's four arguments, not one.
If variadic macros are not available (e.g., C++98), you can take advantage of the fact that "abc" "def"
will be turned into "abcdef"
by the compiler. See it live:
#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))
For this version, your autogenerated tuple must generate a size as well. It's entirely possible to generate a tuple (size, (elems))
that you can use with this macro.
Upvotes: 3