Home > Mobile >  BOOST_PP_SEQ_FOR_EACH cannot expand as expected
BOOST_PP_SEQ_FOR_EACH cannot expand as expected

Time:01-23

Code as below or on godbolt.

#include <boost/preprocessor/seq/enum.hpp>
#include <boost/preprocessor/seq/for_each.hpp>
#include <boost/preprocessor/seq/seq.hpp>
#include <boost/preprocessor/seq/transform.hpp>
#include <boost/preprocessor/seq/elem.hpp>

#define APPLY_MACRO(state, macro, elem) macro(elem)

// (type)(name) --> type
#define PARAM_TYPE(seq) \
    BOOST_PP_SEQ_ELEM(0, seq)

// ((type1)(name1))((type2)(name2))...((typeN)(nameN)) -> type1, type2, ... , typeN
#define PARAMS_TYPE_ENUM(seq) \
    BOOST_PP_SEQ_ENUM(BOOST_PP_SEQ_TRANSFORM(APPLY_MACRO, PARAM_TYPE, seq))

#define PARAMS_TYPE_ENUM2(r, data, seq) \
    BOOST_PP_SEQ_ENUM(BOOST_PP_SEQ_TRANSFORM(APPLY_MACRO, PARAM_TYPE, seq))

PARAMS_TYPE_ENUM (   ((typename)(T)) ((bool)(b)) ) // test -> typename, bool
PARAMS_TYPE_ENUM2(,, ((typename)(T)) ((bool)(b)) ) // test -> typename, bool

BOOST_PP_SEQ_FOR_EACH( APPLY_MACRO, PARAMS_TYPE_ENUM, ( ((typename)(T)) ((bool)(b)) ) ) // cannot expand
BOOST_PP_SEQ_FOR_EACH( PARAMS_TYPE_ENUM2, _, ( ((typename)(T)) ((bool)(b)) ) ) // typename, bool

BOOST_PP_SEQ_FOR_EACH(macro, data, seq) will expand to

macro(r, data, a) macro(r, data, b) macro(r, data, c)

I came up with this APPLY_MACRO as the 'macro' in BOOST_PP_SEQ_FOR_EACH and use the real macro (e.g. PARAM_TYPE and PARAMS_TYPE_ENUM) that takes an element in the seq as the 'data'.

But the second to last line cannot expand as expected. It expands to

APPLY_MACRO(1, PARAM_TYPE, (typename)(T)), APPLY_MACRO(2, PARAM_TYPE, (bool)(b))

The last line which is the traditional way expands as expected.

Why can't the second to last line be expanded to "typename, bool"? Is this APPLY_MACRO PARAMS_TYPE_ENUM as data a wrong practice for BOOST_PP_SEQ_FOR_EACH?

CodePudding user response:

You can't apply one macro twice. The macro is "painted blue".

BOOST_PP_SEQ_FOR_EACH( APPLY_MACRO, ...
# APPLY_MACRO is expanded inside PP_SEQ_FOR_EACH
> APPLY_MACRO(..., PARAMS_TYPE_ENUM, elem) PARAMS_TYPE_ENUM(elem)
> PARAMS_TYPE_ENUM(elem)
> BOOST_PP_SEQ_ENUM(BOOST_PP_SEQ_TRANSFORM(APPLY_MACRO, ....
# You can't expand again same macro.
> APPLY_MACRO(...)

Use a different name, or explore how boost does it with _R macros like BOOST_PP_SEQ_FOR_EACH_R.

  • Related