Pre-Processing loop

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Itay

    Pre-Processing loop

    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.
  • Victor Bazarov

    #2
    Re: Pre-Processing loop

    "Itay" <itaye@nur.co m> wrote...[color=blue]
    > 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[/color]
    like:[color=blue]
    >
    > 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[/color]

    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


    Comment

    • Jeff F

      #3
      Re: Pre-Processing loop


      "Victor Bazarov" <v.Abazarov@com Acast.net> wrote in message
      news:Ettrb.1119 02$275.317876@a ttbi_s53...[color=blue]
      > "Itay" <itaye@nur.co m> wrote...[color=green]
      > > 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[/color]
      > like:[color=green]
      > >
      > > 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[/color]
      >
      > 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.[/color]

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

      Jeff

      Comment

      • Victor Bazarov

        #4
        Re: Pre-Processing loop

        "Jeff F" <Post@ThisNewsG roup.com> wrote...[color=blue]
        >
        > "Victor Bazarov" <v.Abazarov@com Acast.net> wrote in message
        > news:Ettrb.1119 02$275.317876@a ttbi_s53...[color=green]
        > > "Itay" <itaye@nur.co m> wrote...[color=darkred]
        > > > 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[/color][/color][/color]
        something[color=blue][color=green]
        > > like:[color=darkred]
        > > >
        > > > 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[/color]
        > >
        > > 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.[/color]
        >
        > See the Boost Preprocessor Library at www.boost.org.[/color]

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


        Comment

        • Paul Mensonides

          #5
          Re: Pre-Processing loop

          Victor Bazarov wrote:[color=blue]
          > "Jeff F" <Post@ThisNewsG roup.com> wrote...[/color]

          [...]
          [color=blue][color=green][color=darkred]
          >>> And, no, AFAIK, there are no means in C++ preprocessor to make
          >>> recursive macro expansions that could stop based on its argument
          >>> value.[/color]
          >>
          >> See the Boost Preprocessor Library at www.boost.org.[/color]
          >
          > So, what's the solution? Post it, don't tease.[/color]

          #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


          Comment

          • Victor Bazarov

            #6
            Re: Pre-Processing loop

            "Paul Mensonides" <leavings@comca st.net> wrote...[color=blue]
            > Victor Bazarov wrote:[color=green]
            > > "Jeff F" <Post@ThisNewsG roup.com> wrote...[/color]
            >
            > [...]
            >[color=green][color=darkred]
            > >>> 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.[/color]
            > >
            > > So, what's the solution? Post it, don't tease.[/color]
            >
            > #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)[/color]


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

            Thanks.



            Comment

            • Paul Mensonides

              #7
              Re: Pre-Processing loop

              "Victor Bazarov" <v.Abazarov@com Acast.net> wrote in message
              news:5iNrb.1196 81$9E1.586934@a ttbi_s52...
              [color=blue][color=green][color=darkred]
              > > > So, what's the solution? Post it, don't tease.[/color]
              > >
              > > #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)[/color]
              >
              >
              > Interesting. Only I can't use it. My compiler doesn't come with
              > those headers. Any solution in terms of standard C++?[/color]

              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 multidimensiona l, 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(S PLIT_, 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(D EC_, x))
              #define INC(x) SPLIT(1, PRIMITIVE_CAT(D EC_, 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(C OMPL_, 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_NULLAR Y(PRIMITIVE_CAT (BOOL_, x)))
              #define BOOL_0 ()

              // recursion backend
              #define EXPR(s) PRIMITIVE_CAT(E XPR_, 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(I IF_, 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(E AT_, 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)(REPEA T_II, EAT(6))(OBSTRUC T(), s, o, DEC(count), macro, data) \
              /**/
              #define REPEAT_II(_, s, o, count, macro, data) \
              EXPR(s) _(REPEAT_INDIRE CT _()( \
              INC(s), o, count, macro, data \
              )) \
              EXPR OBSTRUCT()(o)(m acro 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)

              // multidimensiona l 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_TEMPLA TE(n) EXPR(0)(REPEAT( 0, n, TTP, ~))

              TEMPLATE_TEMPLA TE(3)

              Boost.Preproces sor 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


              Comment

              • Itay

                #8
                Re: Pre-Processing loop

                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.

                Comment

                • Dan Cernat

                  #9
                  Re: Pre-Processing loop

                  itaye@nur.com (Itay) wrote in message news:<31d72880. 0311110214.695a e0a9@posting.go ogle.com>...[color=blue]
                  > 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.[/color]

                  Victor posted a simple solution.

                  Comment

                  • Paul Mensonides

                    #10
                    Re: Pre-Processing loop

                    Dan Cernat wrote:[color=blue]
                    > itaye@nur.com (Itay) wrote in message
                    > news:<31d72880. 0311110214.695a e0a9@posting.go ogle.com>...[color=green]
                    >> 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.[/color]
                    >
                    > Victor posted a simple solution.[/color]

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

                    Regards,
                    Paul Mensonides


                    Comment

                    Working...