Boost logo

Boost :

From: Paul Mensonides (pmenso57_at_[hidden])
Date: 2004-03-21 17:48:47


> -----Original Message-----
> [mailto:boost-bounces_at_[hidden]] On Behalf Of Larry Evans
> Subject: [boost] BOOST_PP_COMMA, LPAREN,RPAREN delay eval?

> BOOST_PP_REPEAT( 2, PP_CTOR_FORWARDER_OVERLOAD,
> (source,auto_ptr<target>
> BOOST_PP_LPAREN() new target, BOOST_PP_RPAREN() ))

Yeah, this will definitely fail because the data argument will immediately
expand to "(source, auto_ptr<target>(new target,))". The left and right
parentheses as well as the comma are operative preprocessing tokens to the
preprocessor. The corresponding macros expand directly to them. That is fine,
through one level of scanning, but not more:

#define ID(x) x

ID(BOOST_PP_LPAREN()) // okay, expands to: (

#define A(x) B(x)
#define B(x) x

A(BOOST_PP_LPAREN()) // error

The Boost pp-lib cannot do the delay required to make this work properly.
However, there are other methods of overloading an interface. Will something
like this work instead?

#include <boost/preprocessor/arithmetic/inc.hpp>
#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/comparison/equal.hpp>
#include <boost/preprocessor/control/expr_iif.hpp>
#include <boost/preprocessor/repetition/enum.hpp>
#include <boost/preprocessor/repetition/enum_params.hpp>
#include <boost/preprocessor/repetition/repeat.hpp>
#include <boost/preprocessor/seq/elem.hpp>
#include <boost/preprocessor/seq/size.hpp>

#define PP_CTOR_FORWARDER_PARAM(z, n, _) \
    at_c<VecOfTypes, n>::type BOOST_PP_CAT(a, n) \
    /**/

// data :=
// (source)(destination)
// (source)(destination)(super-class)

#define PP_CTOR_FORWARDER_OVERLOAD(z, n, data) \
    template<typename VecOfTypes> \
    BOOST_PP_SEQ_ELEM(0, data)( \
        VecOfTypes const&, \
        BOOST_PP_ENUM( \
            BOOST_PP_INC(n), \
            PP_CTOR_FORWARDER_PARAM, \
            ~ \
        ) \
    ) \
    : BOOST_PP_IIF( \
        BOOST_PP_EQUAL(BOOST_PP_SEQ_SIZE(data), 2), \
        PP_CTOR_FORWARDER_OVERLOAD_A, \
        PP_CTOR_FORWARDER_OVERLOAD_B \
    )(n, data) \
    /**/
#define PP_CTOR_FORWARDER_OVERLOAD_A(n, data) \
    BOOST_PP_SEQ_ELEM(1, data)( \
        BOOST_PP_ENUM_PARAMS(BOOST_PP_INC(n), a) \
    ) \
    /**/
#define PP_CTOR_FORWARDER_OVERLOAD_B(n, data) \
    BOOST_PP_SEQ_ELEM(2, data)( \
        PP_CTOR_FORWARDER_OVERLOAD_A(n, data) \
    ) \
    /**/

BOOST_PP_REPEAT(
    2,
    PP_CTOR_FORWARDER_OVERLOAD,
    (source)(my_target)
)

BOOST_PP_REPEAT(
    2,
    PP_CTOR_FORWARDER_OVERLOAD,
    (source)(new target)(auto_ptr<target>)
)

(Note that two more helper macros are required because the Boost pp-lib doesn't
do lazy evaluation. If it did, the two _A and _B helpers would be unnecessary.)

Regards,
Paul Mensonides


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk