Boost logo

Boost Users :

Subject: Re: [Boost-users] [Preprocessor] Is it possible to expand recursively?
From: Edward Diener (eldiener_at_[hidden])
Date: 2011-07-19 09:55:29


On 7/18/2011 4:04 AM, TONGARI wrote:
> 2011/7/18 Edward Diener <eldiener_at_[hidden]
> <mailto:eldiener_at_[hidden]>>
>
> On 7/17/2011 1:29 PM, Edward Diener wrote:
>
> On 7/17/2011 9:21 AM, TONGARI wrote:
>
> Hello,
>
> I'd like to have a macro like:
>
> BUILD_HIERARCHY
> (a,
> (b,)
> (c,
> (d,)
> (e,)
> )
> )
>
> which should expand to:
>
> struct a {};
> struct b: a {};
> struct c: a {};
> struct d: c {};
> struct e: c {};
>
> Is this possible at all?
> I have tried but with no luck, if this is impossible, please
> tell me so.
>
>
> I think you want above:
>
> (a,
> (b)
> (c,
> (d)
> (e)
> )
> )
>
> This is a tuple with a possible second element as a seq. Each
> element of
> your seq is a tuple with the same rule as the top tuple.
>
> Following internal logic, perhaps with nested BOOST_PP_WHILEs, you
> should be able to cycle through each tuple and nested tuple
> forming the
> relationships you have created for your structs above. I can not
> guarantee this will be doable but at least you should have some
> idea of
> what to do from the description of what you have.
>
>
> I have to correct the above. The syntax for what I described must be:
>
> (a,
> ((b))
> ((c,
> (d)
> (e))
> )
>
> )
>
>
> I think I need the comma since I don't assume variadic macro.

I do not understand what you mean by that, and what some extra comma has
to do with variadic macros

I still do not have the above right. It should be:

(a,
    ((b))
    ((c,
        ((d))
        ((e))
     )
    )
)

In other words, each base-class/derived-classes relationship is a tuple
where the first element is the base class name and where each optional
second element is a sequence of derived classes in the form of your
tuple again.

If you can not use variadic macros you can change your pp-tuples above
to pp-arrays so you have the tuple size of either 1 or 2. So without
variadic macros your relationship above would be:

(2,(a,
      ((1,(b)))
      ((2,(c,
          ((1,(d)))
          ((1,(e)))
       )
     )
    )
))

>
> This is what I had (not working, of course):
>
> #define PACK_2A( a1, a2 ) ((a1, a2)) PACK_2B
> #define PACK_2B( a1, a2 ) ((a1, a2)) PACK_2A
> #define PACK_2A_END
> #define PACK_2B_END
>
> #define BUILD_SUB( x, parent, child ) \
> struct BOOST_PP_TUPLE_ELEM(2, 0, child) : parent {};\
> BOOST_PP_SEQ_FOR_EACH\
> (\
> BUILD_SUB, BOOST_PP_TUPLE_ELEM(2, 0, child)\
> , BOOST_PP_CAT(BOOST_PP_EXPAND(PACK_2A BOOST_PP_TUPLE_ELEM(2, 1,
> child)), _END)\
> )
>
> #define BUILD_HIERARCHY( root, children ) \
> struct root {};\
> BOOST_PP_SEQ_FOR_EACH\
> (\
> BUILD_SUB, root\
> , BOOST_PP_CAT(PACK_2A children, _END)\
> )
>
> Obviously BUILD_SUB cannot be that way since the preprocessor disallows
> recursion.
> But even if I replace the recursive BUILD_SUB with something else the
> BOOST_PP_SEQ_FOR_EACH inside BUILD_SUB still fails to expand.
>
> I have no ideas :/

Just in case you do not know, you can use the Wave trace facility to see
how your macros above are expanding when you invoke BUILD_HIERARCHY with
your two parameters.


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net