[prev in list] [next in list] [prev in thread] [next in thread] 

List:       boost-users
Subject:    [Boost-users] [PP] comma in macro expansions
From:       Marc Mutz <marc () klaralvdalens-datakonsult ! se>
Date:       2006-03-11 18:45:35
Message-ID: 200603111945.36738.marc () klaralvdalens-datakonsult ! se
[Download RAW message or body]

Hi,

I'm having a problem with "free" commas in macro expansions. I want to 
generate some function declarations (and implementations) from a 
user-supplied BOOST_PP_SEQ. The function declarations use enable_if to switch 
between two sets of interfaces based on the type that shall be returned. 
Nevermind the details, I've just used a trivial enabling condition here, the 
error is the same as when using mpl::contains<sometype, Type> in the real 
code. I've stripped the problem down and attached a test file, complete with 
my documented attempts to delay expansion of the comma somehow. The 
preprocessor succeeds when the enable_if or it's two template args are put 
into (parentheses), but this is no longer valid C++, of course.

I guess I'm missing something, but I'm at the end of my Latin, as we say in 
Germany.

Thanks,
Marc

-- 
Marc Mutz -- marc@klaralvdalens-datakonsult.se, mutz@kde.org
Klarälvdalens Datakonsult AB, Platform-independent software solutions

["func_gen.cpp" (text/x-c++src)]

#include <boost/preprocessor.hpp>
#include <boost/utility/enable_if.hpp>

#define SEQ \
    ( ( double, prop1 ) ) \
    ( ( float, prop2  ) ) \
    ( () )

#define OSD_apply( r, macro, tuple ) macro tuple

// this is just a BOOST_PP_SEQ_FOR_EACH that strips the (())
// placeholder at the end of sequences, so's to allow empty sequences:
#define OSD_SEQ_FOR_EACH_BUT_LAST( macro, data, seq )                   \
    BOOST_PP_IF( BOOST_PP_GREATER( BOOST_PP_SEQ_SIZE( seq ), 1 ),       \
                 BOOST_PP_SEQ_FOR_EACH( macro, data, BOOST_PP_SEQ_POP_BACK( seq ) ), \
)

#if TRY == 1
#define OSD_declare( Type, Name ) \
    boost::enable_if_c<true, Type> Name() const;
#endif

#if TRY == 2
#define OSD_declare( Type, Name ) \
    boost::enable_if_c<BOOST_PP_SEQ_ENUM( ( true )( Type ) )> Name() const;
#endif

#if TRY == 3
#define OSD_declare( Type, Name ) \
    boost::enable_if_c<OSD_apply( BOOST_PP_SEQ_ENUM, ( ( true )( Type ) ) )> Name() \
const; #endif

#if TRY == 4
#define OSD_declare( Type, Name ) \
    boost::enable_if_c<true BOOST_PP_COMMA() Type> Name() const;
#endif

#if TRY == 5
#define OSD_declare( Type, Name ) \
    boost::enable_if_c<true BOOST_PP_COMMA_IF(1) Type> Name() const;
#endif

#if TRY == 6
#define OSD_declare( Type, Name )                                     \
    boost::enable_if_c<true BOOST_PP_IF( 1, BOOST_PP_COMMA, BOOST_PP_EMPTY )() Type> \
Name() const; #endif

class Foo {
public:
#if 1 <= TRY && TRY <= 6
    OSD_SEQ_FOR_EACH_BUT_LAST( OSD_apply, OSD_declare, SEQ )
#endif
#if TRY == 7
# define OSD_declare( r, data, item ) \
    boost::enable_if_c<true, BOOST_PP_TUPLE_ELEM( 2, 0, item )> BOOST_PP_TUPLE_ELEM( \
2, 1, item )() const;

    OSD_SEQ_FOR_EACH_BUT_LAST( OSD_declare, ~, SEQ )
#endif

};



[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic