By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,413 Members | 996 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,413 IT Pros & Developers. It's quick & easy.

Pre-Processing loop

P: n/a
Hi all ,

Suppose i have structurs defines as follows :
struct S1
{
int n1 ;
int n2 ;
int n3 ;
};

struct S2
{
int i1 ;
int i2 ;
int i3 ;
};

i need to copy each member from S1 to it's corresponding in S2 something like:

s1.n1 = s2.i1 ;
s1.n2 = s2.i2 ;
s1.n3 = s2.i3 ;

is there a way to create those line in a macro ???
what i need is something like :

#define COPY(n)
#if ( n != 0 )
copy n to i\
COPY(n-1) \ reccursive call
#endif

BTW : i'm using vc++ compiler (and preprocessor).

Thanks.
Jul 19 '05 #1
Share this Question
Share on Google+
9 Replies


P: n/a
"Itay" <it***@nur.com> wrote...
Suppose i have structurs defines as follows :
struct S1
{
int n1 ;
int n2 ;
int n3 ;
};

struct S2
{
int i1 ;
int i2 ;
int i3 ;
};

i need to copy each member from S1 to it's corresponding in S2 something like:
s1.n1 = s2.i1 ;
s1.n2 = s2.i2 ;
s1.n3 = s2.i3 ;

is there a way to create those line in a macro ???
what i need is something like :

#define COPY(n)
#if ( n != 0 )
copy n to i\
COPY(n-1) \ reccursive call
#endif


If the layouts of the two structures are really so much the same,
why don't you use some kind of low-end memcpy routine? If the
layouts are not the same (as to prohibit the use of memcpy), why
not have a simple function that would do the copying for you

void copyints(S1& s1, S2 const& s2) {
s1.n1 = s2.i1 ;
s1.n2 = s2.i2 ;
s1.n3 = s2.i3 ;
}

? Why do you need to involve a preprocessor at all?

And, no, AFAIK, there are no means in C++ preprocessor to make
recursive macro expansions that could stop based on its argument
value.

Victor
Jul 19 '05 #2

P: n/a

"Victor Bazarov" <v.********@comAcast.net> wrote in message
news:Ettrb.111902$275.317876@attbi_s53...
"Itay" <it***@nur.com> wrote...
Suppose i have structurs defines as follows :
struct S1
{
int n1 ;
int n2 ;
int n3 ;
};

struct S2
{
int i1 ;
int i2 ;
int i3 ;
};

i need to copy each member from S1 to it's corresponding in S2 something

like:

s1.n1 = s2.i1 ;
s1.n2 = s2.i2 ;
s1.n3 = s2.i3 ;

is there a way to create those line in a macro ???
what i need is something like :

#define COPY(n)
#if ( n != 0 )
copy n to i\
COPY(n-1) \ reccursive call
#endif


If the layouts of the two structures are really so much the same,
why don't you use some kind of low-end memcpy routine? If the
layouts are not the same (as to prohibit the use of memcpy), why
not have a simple function that would do the copying for you

void copyints(S1& s1, S2 const& s2) {
s1.n1 = s2.i1 ;
s1.n2 = s2.i2 ;
s1.n3 = s2.i3 ;
}

? Why do you need to involve a preprocessor at all?

And, no, AFAIK, there are no means in C++ preprocessor to make
recursive macro expansions that could stop based on its argument
value.


See the Boost Preprocessor Library at www.boost.org.

Jeff

Jul 19 '05 #3

P: n/a
"Jeff F" <Po**@ThisNewsGroup.com> wrote...

"Victor Bazarov" <v.********@comAcast.net> wrote in message
news:Ettrb.111902$275.317876@attbi_s53...
"Itay" <it***@nur.com> wrote...
Suppose i have structurs defines as follows :
struct S1
{
int n1 ;
int n2 ;
int n3 ;
};

struct S2
{
int i1 ;
int i2 ;
int i3 ;
};

i need to copy each member from S1 to it's corresponding in S2
something like:

s1.n1 = s2.i1 ;
s1.n2 = s2.i2 ;
s1.n3 = s2.i3 ;

is there a way to create those line in a macro ???
what i need is something like :

#define COPY(n)
#if ( n != 0 )
copy n to i\
COPY(n-1) \ reccursive call
#endif


If the layouts of the two structures are really so much the same,
why don't you use some kind of low-end memcpy routine? If the
layouts are not the same (as to prohibit the use of memcpy), why
not have a simple function that would do the copying for you

void copyints(S1& s1, S2 const& s2) {
s1.n1 = s2.i1 ;
s1.n2 = s2.i2 ;
s1.n3 = s2.i3 ;
}

? Why do you need to involve a preprocessor at all?

And, no, AFAIK, there are no means in C++ preprocessor to make
recursive macro expansions that could stop based on its argument
value.


See the Boost Preprocessor Library at www.boost.org.


So, what's the solution? Post it, don't tease.
Jul 19 '05 #4

P: n/a
Victor Bazarov wrote:
"Jeff F" <Po**@ThisNewsGroup.com> wrote...


[...]
And, no, AFAIK, there are no means in C++ preprocessor to make
recursive macro expansions that could stop based on its argument
value.


See the Boost Preprocessor Library at www.boost.org.


So, what's the solution? Post it, don't tease.


#include <boost/preprocessor/arithmetic/inc.hpp>
#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/repetition/repeat.hpp>

#define COPY_M(z, v, _) \
s1.BOOST_PP_CAT(n, BOOST_PP_INC(v)) \
= s2.BOOST_PP_CAT(i, BOOST_PP_INC(v)); \
/**/
#define COPY(n) BOOST_PP_REPEAT(n, COPY_M, ~)

COPY(3)

Regards,
Paul Mensonides
Jul 19 '05 #5

P: n/a
"Paul Mensonides" <le******@comcast.net> wrote...
Victor Bazarov wrote:
"Jeff F" <Po**@ThisNewsGroup.com> wrote...


[...]
And, no, AFAIK, there are no means in C++ preprocessor to make
recursive macro expansions that could stop based on its argument
value.

See the Boost Preprocessor Library at www.boost.org.


So, what's the solution? Post it, don't tease.


#include <boost/preprocessor/arithmetic/inc.hpp>
#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/repetition/repeat.hpp>

#define COPY_M(z, v, _) \
s1.BOOST_PP_CAT(n, BOOST_PP_INC(v)) \
= s2.BOOST_PP_CAT(i, BOOST_PP_INC(v)); \
/**/
#define COPY(n) BOOST_PP_REPEAT(n, COPY_M, ~)

COPY(3)

Interesting. Only I can't use it. My compiler doesn't come with
those headers. Any solution in terms of standard C++?

Thanks.

Jul 19 '05 #6

P: n/a
"Victor Bazarov" <v.********@comAcast.net> wrote in message
news:5iNrb.119681$9E1.586934@attbi_s52...
So, what's the solution? Post it, don't tease.


#include <boost/preprocessor/arithmetic/inc.hpp>
#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/repetition/repeat.hpp>

#define COPY_M(z, v, _) \
s1.BOOST_PP_CAT(n, BOOST_PP_INC(v)) \
= s2.BOOST_PP_CAT(i, BOOST_PP_INC(v)); \
/**/
#define COPY(n) BOOST_PP_REPEAT(n, COPY_M, ~)

COPY(3)

Interesting. Only I can't use it. My compiler doesn't come with
those headers. Any solution in terms of standard C++?


Certainly. The following implements the scaffolding required to implement a
generic repetition construct, a generic repetititon construct, and then the use
of that construct to generate the assignments.

This is "standard C++" which means that it won't work on most preprocessors
(e.g. not VC, not EDG, not Sun, not IBM, not Borland, and not Metrowerks).
Preprocessors that are compliant enough include Wave, GCC, Borland's free
command line preprocessor (the non-integrated one), and probably Metrowerks' new
preprocessor available with their version 9 Macintosh compiler.

The following implementation can only repeat something nine times. In order to
increase that limit, you need to increase the number of DEC_x macros and the
number of EXPR_x macros such that they go as high as necessary. However, the
construct is multidimensional, and the invocations of the external macros are
trampolined. In other words, the first dimension can repeat nine elements, the
second dimension can repeat eight elements, the third dimension can repeat seven
elements, and so on.

// concatenation
#define CAT(a, b) PRIMITIVE_CAT(a, b)
#define PRIMITIVE_CAT(a, b) a ## b

// binary intermediate split
#define SPLIT(i, im) PRIMITIVE_CAT(SPLIT_, i)(im)
#define SPLIT_0(a, b) a
#define SPLIT_1(a, b) b

// saturating increment and decrement
#define DEC(x) SPLIT(0, PRIMITIVE_CAT(DEC_, x))
#define INC(x) SPLIT(1, PRIMITIVE_CAT(DEC_, x))

#define DEC_0 0, 1
#define DEC_1 0, 2
#define DEC_2 1, 3
#define DEC_3 2, 4
#define DEC_4 3, 5
#define DEC_5 4, 6
#define DEC_6 5, 7
#define DEC_7 6, 8
#define DEC_8 7, 9
#define DEC_9 8, 9

// bit complement
#define COMPL(bit) PRIMITIVE_CAT(COMPL_, bit)
#define COMPL_0 1
#define COMPL_1 0

// nullary parentheses detection
#define IS_NULLARY(x) SPLIT(0, CAT(IS_NULLARY_R_, IS_NULLARY_C x))
#define IS_NULLARY_C() 1
#define IS_NULLARY_R_1 1, ~
#define IS_NULLARY_R_IS_NULLARY_C 0, ~

// boolean conversion
#define BOOL(x) COMPL(IS_NULLARY(PRIMITIVE_CAT(BOOL_, x)))
#define BOOL_0 ()

// recursion backend
#define EXPR(s) PRIMITIVE_CAT(EXPR_, s)
#define EXPR_0(x) x
#define EXPR_1(x) x
#define EXPR_2(x) x
#define EXPR_3(x) x
#define EXPR_4(x) x
#define EXPR_5(x) x
#define EXPR_6(x) x
#define EXPR_7(x) x
#define EXPR_8(x) x
#define EXPR_9(x) x

// bit-oriented if control structure
#define IIF(bit) PRIMITIVE_CAT(IIF_, bit)
#define IIF_0(t, f) f
#define IIF_1(t, f) t

// number-oriented if control structure
#define IF(cond) IIF(BOOL(cond))

// emptiness abstraction
#define EMPTY()

// 1x and 2x deferral macros
#define DEFER(macro) macro EMPTY()
#define OBSTRUCT() DEFER(EMPTY)()

// argument list eater
#define EAT(size) PRIMITIVE_CAT(EAT_, size)
#define EAT_0()
#define EAT_1(a)
#define EAT_2(a, b)
#define EAT_3(a, b, c)
#define EAT_4(a, b, c, d)
#define EAT_5(a, b, c, d, e)
#define EAT_6(a, b, c, d, e, f)

// comma abstractions
#define COMMA() ,
#define COMMA_IF(n) IF(n)(COMMA, EMPTY)()

// repetition construct
#define REPEAT(s, count, macro, data) \
EXPR(s)(REPEAT_I(INC(s), INC(s), count, macro, data)) \
/**/
#define REPEAT_INDIRECT() REPEAT_I
#define REPEAT_I(s, o, count, macro, data) \
IF(count)(REPEAT_II, EAT(6))(OBSTRUCT(), s, o, DEC(count), macro, data) \
/**/
#define REPEAT_II(_, s, o, count, macro, data) \
EXPR(s) _(REPEAT_INDIRECT _()( \
INC(s), o, count, macro, data \
)) \
EXPR OBSTRUCT()(o)(macro OBSTRUCT()(o, count, data)) \
/**/

// original example
#define COPY_M(s, v, _) s1.CAT(n, INC(v)) = s2.CAT(i, INC(v));
#define COPY(n) EXPR(0)(REPEAT(0, n, COPY_M, ~))

COPY(3)

// multidimensional example (template template parameters)
#define FIXED(s, n, text) COMMA_IF(n) text
#define TTP(s, n, _) \
COMMA_IF(n) template<REPEAT(s, INC(n), FIXED, class)> class T ## n \
/**/
#define TEMPLATE_TEMPLATE(n) EXPR(0)(REPEAT(0, n, TTP, ~))

TEMPLATE_TEMPLATE(3)

Boost.Preprocessor cannot get away with this level of abstraction because it
requires a strictly conforming preprocessor. This is similar to the way Chaos
generalizes recursion. Most of the above are general purpose library facilities
(rather than the means to implement the trivial example in question). Hence, it
is better to just get Boost (though I realize that you were just being strictly
topical).

Regards,
Paul Mensonides
Jul 19 '05 #7

P: n/a
Whhoow ,
Thanks for the replies.
Actually i was looking for a much simplier solution.
I'm not familar with the boost libraries though i heard it good.
Can someone apply a simple solution to the simple sample i posted ???

Thanks.
Jul 19 '05 #8

P: n/a
it***@nur.com (Itay) wrote in message news:<31**************************@posting.google. com>...
Whhoow ,
Thanks for the replies.
Actually i was looking for a much simplier solution.
I'm not familar with the boost libraries though i heard it good.
Can someone apply a simple solution to the simple sample i posted ???

Thanks.


Victor posted a simple solution.
Jul 19 '05 #9

P: n/a
Dan Cernat wrote:
it***@nur.com (Itay) wrote in message
news:<31**************************@posting.google. com>...
Whhoow ,
Thanks for the replies.
Actually i was looking for a much simplier solution.
I'm not familar with the boost libraries though i heard it good.
Can someone apply a simple solution to the simple sample i posted ???

Thanks.


Victor posted a simple solution.


Yes, Victor's solution is the way to go in this case.

Regards,
Paul Mensonides
Jul 19 '05 #10

This discussion thread is closed

Replies have been disabled for this discussion.