Boost logo

Boost Users :

Subject: Re: [Boost-users] Preprocessor sequence of "pairs"
From: Nathan Ridge (zeratul976_at_[hidden])
Date: 2012-09-26 03:44:54


> What I want to do is something like the following:
>
> #include <boost/preprocessor/seq/for_each.hpp>
>
> #define DEFINE_FIELD(r, os, field_pair) [....]
>
> #define DEFINE_STRUCT(struct_name, fields) \
> struct struct_name { \
> BOOST_PP_SEQ_FOR_EACH(DEFINE_FIELD, ~, fields) \
> }
>
> DEFINE_STRUCT(mystruct, (int, x)(int, y)(double, z))
>
> but this doesn't work, because the sequence is made up of pairs instead of
> single preprocessor arguments. (GCC complains about "macro
> "BOOST_PP_SEQ_SIZE_0" passed 2 arguments, but takes just 1" and same for
> PP_EXPR_IIF_0.)
>
> I can get it to work by double-parenthesizing the stuff in the sequence
> (saying "((int, x))((int, y))((double, z))") then defining DEFINE_FIELD as
> follows:
>
> #define DEFINE_FIELD_REAL(type, name) type name;
> #define DEFINE_FIELD(r, os, field_pair) DEFINE_FIELD_REAL field_pair
>
> but this is less than optimal. Is there a way that I can do this easily,
> or would I effectively have to re-implement SEQ_FOR_EACH? (And how hard
> would that be if it's necessary?)

Given INPUT of the form (a1, b1)(a2, b2)(a3, b3)...(an, bn)

you can transform it into OUTPUT of the form ((a1, b1))((a2, b2))((a3, b3))...((an, bn))

as follows:

#define ADD_PAREN_1(A, B) ((A, B)) ADD_PAREN_2
#define ADD_PAREN_2(A, B) ((A, B)) ADD_PAREN_1
#define ADD_PAREN_1_END
#define ADD_PAREN_2_END
#define OUTPUT BOOST_PP_CAT(ADD_PAREN_1 INPUT,_END)

You can then process the double-parenthesized sequence with SEQ_FOR_EACH
like you want.

Regards,
Nate
                                               


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