preprocessor question

Discussion in 'C++' started by David Resnick, Dec 1, 2008.

  1. Given this code fragment:

    #define IFV(func, number) \
    incomingFunctVal<CVxicBridgedXferIncomingAction> val##number
    ( \
    number, &CVxicBridgedXferIncomingAction::func); \
    m_transFnMap.insert(fnMap::value_type(#func, val##number));

    IFV( DoJoin, 1 );
    IFV( DoJoinRestartReco, 2 );
    IFV( DummyAction, 3 );
    IFV( RestartReco, 4 );
    ....
    IFV( SomeFunc, 100 );

    I'm wondering if there is a way to have the numbers in the function
    macro increment automatically?
    The code in the macro isn't really subject to change (it is the way to
    use a state machine
    implementation that I can't modify). I'm just finding it to be a
    maintenance pain when
    I want to delete a function with a middle number. I've been swapping
    the last
    function into the place of the deleted one to avoid renumbering the
    rest, which is
    OK in that order doesn't matter, but is there a better way? The fact
    that ## is
    used to glue the number into an identifier makes me doubt that this
    can be repaired,
    but I'd be very happy to be proved wrong.

    Thanks!

    -David
     
    David Resnick, Dec 1, 2008
    #1
    1. Advertising

  2. David Resnick

    Guest

    On Dec 1, 10:16 am, David Resnick <> wrote:
    > Given this code fragment:
    >
    >         #define IFV(func, number) \
    >         incomingFunctVal<CVxicBridgedXferIncomingAction> val##number
    > ( \
    >             number, &CVxicBridgedXferIncomingAction::func); \
    >         m_transFnMap.insert(fnMap::value_type(#func, val##number));
    >
    >         IFV( DoJoin, 1 );
    >         IFV( DoJoinRestartReco, 2 );
    >         IFV( DummyAction, 3 );
    >         IFV( RestartReco, 4 );
    >         ....
    >         IFV( SomeFunc, 100 );
    >
    > I'm wondering if there is a way to have the numbers in the function
    > macro increment automatically?
    > The code in the macro isn't really subject to change (it is the way to
    > use a state machine
    > implementation that I can't modify).  I'm just finding it to be a
    > maintenance pain when
    > I want to delete a function with a middle number.  I've been swapping
    > the last
    > function into the place of the deleted one to avoid renumbering the
    > rest, which is
    > OK in that order doesn't matter, but is there a better way?  The fact
    > that ## is
    > used to glue the number into an identifier makes me doubt that this
    > can be repaired,
    > but I'd be very happy to be proved wrong.
    >
    > Thanks!
    >
    > -David


    First cut, create a function called IFV2 (for instance), with a static
    counter variable that you increment. The call to IFV and the counter
    would be within the function scope.

    Just because someone creates crazy preprocessor programming doesn't
    mean you can't isolate it and use real programming solution to
    minimize it's impact.

    HTH
     
    , Dec 1, 2008
    #2
    1. Advertising

  3. On Dec 1, 3:16 pm, David Resnick <> wrote:
    > Given this code fragment:
    >
    >         #define IFV(func, number) \
    >         incomingFunctVal<CVxicBridgedXferIncomingAction> val##number
    > ( \
    >             number, &CVxicBridgedXferIncomingAction::func); \
    >         m_transFnMap.insert(fnMap::value_type(#func, val##number));
    >
    >         IFV( DoJoin, 1 );
    >         IFV( DoJoinRestartReco, 2 );
    >         IFV( DummyAction, 3 );
    >         IFV( RestartReco, 4 );
    >         ....
    >         IFV( SomeFunc, 100 );
    >
    > I'm wondering if there is a way to have the numbers in the function
    > macro increment automatically?


    You could use __COUNTER__ macro. If it is supported by your compiler.

    Otherwise, draw inspiration from boost preprocessor library:
    http://www.boost.org/doc/libs/1_37_0/libs/preprocessor/doc/ref/counter.html

    > The code in the macro isn't really subject to change (it is the way to
    > use a state machine
    > implementation that I can't modify).


    That's too bad, since such an interface is real pain.

    I wonder why incomingFunctVal<> constructor needs that integer? If it
    can be auto-generated (possibly in incomingFunctVal<> constructor) by
    incrementing a global or class static variable, and if you don't
    really need valN objects (their copies are stored in m_transFnMap
    anyway) the macro could be simplified to:

    typedef CVxicBridgedXferIncomingAction X; // for brevity
    int x = 0; // the global counter

    #define IFV(func) \
    m_transFnMap.insert( \
    fnMap::value_type( \
    #func \
    , incomingFunctVal<X>(++x, &X::func) \
    ) \
    );

    --
    Max
     
    Maxim Yegorushkin, Dec 1, 2008
    #3
  4. On Dec 1, 11:34 am, Maxim Yegorushkin <>
    wrote:
    > On Dec 1, 3:16 pm, David Resnick <> wrote:
    >
    >
    >
    > > Given this code fragment:

    >
    > >         #define IFV(func, number) \
    > >         incomingFunctVal<CVxicBridgedXferIncomingAction> val##number
    > > ( \
    > >             number, &CVxicBridgedXferIncomingAction::func); \
    > >         m_transFnMap.insert(fnMap::value_type(#func, val##number));

    >
    > >         IFV( DoJoin, 1 );
    > >         IFV( DoJoinRestartReco, 2 );
    > >         IFV( DummyAction, 3 );
    > >         IFV( RestartReco, 4 );
    > >         ....
    > >         IFV( SomeFunc, 100 );

    >
    > > I'm wondering if there is a way to have the numbers in the function
    > > macro increment automatically?

    >
    > You could use __COUNTER__ macro. If it is supported by your compiler.
    >
    > Otherwise, draw inspiration from boost preprocessor library:http://www.boost.org/doc/libs/1_37_0/libs/preprocessor/doc/ref/counte...
    >
    > > The code in the macro isn't really subject to change (it is the way to
    > > use a state machine
    > > implementation that I can't modify).

    >
    > That's too bad, since such an interface is real pain.
    >
    > I wonder why incomingFunctVal<> constructor needs that integer? If it
    > can be auto-generated (possibly in incomingFunctVal<> constructor) by
    > incrementing a global or class static variable, and if you don't
    > really need valN objects (their copies are stored in m_transFnMap
    > anyway) the macro could be simplified to:
    >
    >     typedef CVxicBridgedXferIncomingAction X; // for brevity
    >     int x = 0; // the global counter
    >
    >     #define IFV(func) \
    >     m_transFnMap.insert( \
    >         fnMap::value_type( \
    >               #func \
    >             , incomingFunctVal<X>(++x, &X::func) \
    >             ) \
    >         );
    >
    > --
    > Max


    That is a very helpful suggestion, thanks. The use of the integer in
    the original macro (at least the ## version) was apparently just to
    avoid re-declaring identifiers in the same scope, which is fixed by
    your macro.

    -David
     
    David Resnick, Dec 1, 2008
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Dan W.
    Replies:
    9
    Views:
    332
    Paul Mensonides
    Dec 4, 2003
  2. xuatla
    Replies:
    1
    Views:
    367
    Denis Remezov
    Jul 10, 2004
  3. Cronus
    Replies:
    1
    Views:
    676
    Paul Mensonides
    Jul 15, 2004
  4. ³á³á³á³á

    Preprocessor's question

    ³á³á³á³á, Sep 12, 2003, in forum: C Programming
    Replies:
    1
    Views:
    335
    Martin Ambuhl
    Sep 12, 2003
  5. Neil Zanella

    preprocessor question

    Neil Zanella, Nov 6, 2003, in forum: C Programming
    Replies:
    4
    Views:
    324
    Eric Sosman
    Nov 6, 2003
Loading...

Share This Page