how to write a macro like this?

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

    #1

    how to write a macro like this?

    Hi,

    I want a macro #expand that can be expanded to one of the following
    depending on its argument

    f(i1)
    f(i1, i2)
    f(i1, i2, i3)

    ...


    For example,

    expand(1) would give me f(i1)

    expand(2) would give me f(i1, i2)

    expand(3) would give me f(i1, i2, i3)

    Is it possible to be done in macro? If it is possible, could you let
    me know how to do it?

    Thanks,
    Peng
  • Victor Bazarov

    #2
    Re: how to write a macro like this?

    Peng Yu wrote:
    I want a macro #expand that can be expanded to one of the following
    depending on its argument
    >
    f(i1)
    f(i1, i2)
    f(i1, i2, i3)
    >
    ..
    >
    >
    For example,
    >
    expand(1) would give me f(i1)
    >
    expand(2) would give me f(i1, i2)
    >
    expand(3) would give me f(i1, i2, i3)
    >
    Is it possible to be done in macro? If it is possible, could you let
    me know how to do it?
    //--------------------- here you go
    #define with1args f(i1)
    #define with2args f(i1,i2)
    #define with3args f(i1,i2,i3)
    #define formNname(i) with##i##args
    #define expand(i) formNname(i)


    //---------------- test code
    #include <iostream>
    #include <ostream>

    void f(int) { std::cout << "f(int)\n"; }
    void f(int,int) { std::cout << "f(int,int) \n"; }
    void f(int,int,int) { std::cout << "f(int,int,int) \n"; }

    int main()
    {
    int i1=0, i2=0, i3=0;
    expand(1);
    expand(2);
    expand(3);
    }

    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask

    Comment

    • Peng Yu

      #3
      Re: how to write a macro like this?

      On Jun 25, 6:16 pm, Victor Bazarov <v.Abaza...@com Acast.netwrote:
      Peng Yu wrote:
      I want a macro #expand that can be expanded to one of the following
      depending on its argument
      >
      f(i1)
      f(i1, i2)
      f(i1, i2, i3)
      >
      ..
      >
      For example,
      >
      expand(1) would give me f(i1)
      >
      expand(2) would give me f(i1, i2)
      >
      expand(3) would give me f(i1, i2, i3)
      >
      Is it possible to be done in macro? If it is possible, could you let
      me know how to do it?
      >
      //--------------------- here you go
      #define with1args f(i1)
      #define with2args f(i1,i2)
      #define with3args f(i1,i2,i3)
      #define formNname(i) with##i##args
      #define expand(i) formNname(i)
      >
      //---------------- test code
      #include <iostream>
      #include <ostream>
      >
      void f(int) { std::cout << "f(int)\n"; }
      void f(int,int) { std::cout << "f(int,int) \n"; }
      void f(int,int,int) { std::cout << "f(int,int,int) \n"; }
      >
      int main()
      {
      int i1=0, i2=0, i3=0;
      expand(1);
      expand(2);
      expand(3);
      >
      }
      >
      V
      --
      Please remove capital 'A's when replying by e-mail
      I do not respond to top-posted replies, please don't ask
      I think the example in my OP did not reflect the question that I
      wanted to ask.

      Suppose that the definitions of f(int), f(int, int) , f(int, int,
      int) ... in reality are very complex. However, the difference between
      them are minor, except the things that depend on different arguments.
      In this case, I would not want to write each definition individually.

      Also, in the code snippet that you showed, if the user needs f of 10
      arguments, I have to define it ahead of time. But since I can not
      enumerate all the possibilities, what if the user want an f of 100 or
      1000 arguments.

      I suspect that my request can not be done in macro. I looked up the
      code of boost tuple, which offers functions and classes of different
      number of arguments. It did not use macro in implementation in this
      aspect. I just want to double check if my inception is correct.

      Thanks,
      Peng

      Comment

      • Peng Yu

        #4
        Re: how to write a macro like this?

        On Jun 25, 7:45 pm, r...@zedat.fu-berlin.de (Stefan Ram) wrote:
        Peng Yu <PengYu...@gmai l.comwrites:
        Suppose that the definitions of f(int), f(int, int) , f(int, int,
        int) ... in reality are very complex.
        >
        It is usually recommended to refactor a complex function
        definition until it is not so complex anymore.
        >
        However, the difference between
        them are minor, except the things that depend on different arguments.
        In this case, I would not want to write each definition individually.
        >
        One might use a single array or vector as an argument or
        write f as a a function with a variable number of arguments.
        It might be OK to certain cases, but it is not suitable to the cases
        in my project.

        Thanks,
        Peng

        Comment

        • gpderetta

          #5
          Re: how to write a macro like this?

          On Jun 26, 1:51 am, Peng Yu <PengYu...@gmai l.comwrote:
          <snip>
          I suspect that my request can not be done in macro. I looked up the
          code of boost tuple, which offers functions and classes of different
          number of arguments. It did not use macro in implementation in this
          aspect. I just want to double check if my inception is correct.
          >
          Check the boost preprocessor library.

          --
          gpd

          Comment

          • Pascal J. Bourguignon

            #6
            Re: how to write a macro like this?

            Peng Yu <PengYu.UT@gmai l.comwrites:
            On Jun 25, 6:16 pm, Victor Bazarov <v.Abaza...@com Acast.netwrote:
            >Peng Yu wrote:
            I want a macro #expand that can be expanded to one of the following
            depending on its argument
            >>
            f(i1)
            f(i1, i2)
            f(i1, i2, i3)
            >>
            ..
            >>
            For example,
            >>
            expand(1) would give me f(i1)
            >>
            expand(2) would give me f(i1, i2)
            >>
            expand(3) would give me f(i1, i2, i3)
            >>
            Is it possible to be done in macro? If it is possible, could you let
            me know how to do it?
            >>
            >//--------------------- here you go
            >#define with1args f(i1)
            >#define with2args f(i1,i2)
            >#define with3args f(i1,i2,i3)
            >#define formNname(i) with##i##args
            >#define expand(i) formNname(i)
            >>
            >//---------------- test code
            >#include <iostream>
            >#include <ostream>
            >>
            >void f(int) { std::cout << "f(int)\n"; }
            >void f(int,int) { std::cout << "f(int,int) \n"; }
            >void f(int,int,int) { std::cout << "f(int,int,int) \n"; }
            >>
            >int main()
            >{
            > int i1=0, i2=0, i3=0;
            > expand(1);
            > expand(2);
            > expand(3);
            >>
            >}
            >>
            >V
            >--
            >Please remove capital 'A's when replying by e-mail
            >I do not respond to top-posted replies, please don't ask
            >
            I think the example in my OP did not reflect the question that I
            wanted to ask.
            >
            Suppose that the definitions of f(int), f(int, int) , f(int, int,
            int) ... in reality are very complex. However, the difference between
            them are minor, except the things that depend on different arguments.
            In this case, I would not want to write each definition individually.
            >
            Also, in the code snippet that you showed, if the user needs f of 10
            arguments, I have to define it ahead of time. But since I can not
            enumerate all the possibilities, what if the user want an f of 100 or
            1000 arguments.
            >
            I suspect that my request can not be done in macro.
            It can be done, almost. You only need an additionnal cpp loop.







            I looked up the
            code of boost tuple, which offers functions and classes of different
            number of arguments. It did not use macro in implementation in this
            aspect. I just want to double check if my inception is correct.
            You could probably solve your problem with templates (and boost::mpl),
            but I don't think it would be any simplier than with C macros.



            What you are really longing for is merely lisp:

            (defmacro call-f-with-arguments (n)
            `(f ,@(loop :for i :from 1 :to n
            :collect (intern (format nil "I~A" i)))))

            (macroexpand '(call-f-with-arguments 7))
            --(F I1 I2 I3 I4 I5 I6 I7)


            Or with local macros:

            (defun main ()
            (let ((i1 0) (i2 0) (i3 0))
            (macrolet ((call-f (n)
            `(f ,@(loop :for i :from 1 :to n
            :collect (intern (format nil "I~A" i))))))
            (call-f 3)))
            0)

            --
            __Pascal Bourguignon__

            Comment

            Working...