I think I found the issue. It seems that you can't use the # symbol inside of macros without it being treated as a preprocessor operator. I don't know of any way to escape the # character to be treated as part of the macro code. Is there a way I can increment the counter without doing the #include statement? Perhaps there is a different implementation of a counter somewhere that utilizes templates?

Thanks.

On Dec 20, 2007 3:51 PM, Robert Dailey <rcdailey@gmail.com> wrote:
Hi,

I'm currently compiling my code in Visual Studio 2005. Below is the code that utilizes BOOST_PP_COUNTER. Note that the goal here is to increment the counter 1 time each time the CHECK_MATCH_AND_RETURN macro is used. This allows me to make sure that I've got one macro call per enumeration member. The problem I'm having is that I'm getting page after page of compiler error and as far as I can tell I'm using the counter system as it was shown in the code examples. Below I've also listed some of the compiler errors I'm getting:

Compiler Errors:
error C2162: expected macro formal parameter
error C2065: 'include' : undeclared identifier
error C2882: 'boost' : illegal use of namespace identifier in expression


Code:

#include <boost/static_assert.hpp>
#include <boost/preprocessor/slot/counter.hpp>

/// Various camera actions that may be performed.
/// These actions are usually a result of input events.
enum CameraAction
{
      MOVE_FORWARD = 0
    , MOVE_BACKWARD
    , MOVE_LEFT
    , MOVE_RIGHT
    , MOVE_UP
    , MOVE_DOWN
    , ROTATE_RIGHT
    , ROTATE_LEFT
    , ROTATE_UP
    , ROTATE_DOWN
    , ROLL_LEFT
    , ROLL_RIGHT
    , INCREASE_ACCEL
    , DECREASE_ACCEL
    , ENABLE_LOOK
    , TOGGLE_LOOK
    , ENABLE_AUTO_MOVE
    , TOGGLE_AUTO_MOVE

    /// @cond
    , NUM_CAMERAACTIONS
    , CAMERAACTION_NONE
    /// @endcond
};

//=========================================================================================
CameraAction StringToCameraAction( const std::string& str )
{
    // I'm using a macro here because I need the stringizing preprocessor operator (#)
    // to make the conditionals more manageable. By using this macro, I never have to explicitly
    // update the string comparison itself if the enumeration names ever change.
    #define CHECK_MATCH_AND_RETURN( action ) if( str == #action ) { return action; } #include BOOST_PP_UPDATE_COUNTER()

    CHECK_MATCH_AND_RETURN( ROTATE_LEFT )
    CHECK_MATCH_AND_RETURN( ROTATE_RIGHT )
    CHECK_MATCH_AND_RETURN( ROTATE_UP )
    CHECK_MATCH_AND_RETURN( ROTATE_DOWN )
    CHECK_MATCH_AND_RETURN( MOVE_UP )
    CHECK_MATCH_AND_RETURN( MOVE_DOWN )
    CHECK_MATCH_AND_RETURN( MOVE_LEFT )
    CHECK_MATCH_AND_RETURN( MOVE_RIGHT )
    CHECK_MATCH_AND_RETURN( MOVE_FORWARD )
    CHECK_MATCH_AND_RETURN( MOVE_BACKWARD )
    CHECK_MATCH_AND_RETURN( ROLL_RIGHT )
    CHECK_MATCH_AND_RETURN( ROLL_LEFT )
    CHECK_MATCH_AND_RETURN( INCREASE_ACCEL )
    CHECK_MATCH_AND_RETURN( DECREASE_ACCEL )
    CHECK_MATCH_AND_RETURN( ENABLE_LOOK )
    CHECK_MATCH_AND_RETURN( TOGGLE_LOOK )
    CHECK_MATCH_AND_RETURN( ENABLE_AUTO_MOVE )
    CHECK_MATCH_AND_RETURN( TOGGLE_AUTO_MOVE )

    // This helps me remember to add/remove items above.
    BOOST_STATIC_ASSERT( (BOOST_PP_COUNTER)+1 != NUM_CAMERAACTIONS );

    return CAMERAACTION_NONE;
}