Boost logo

Boost Users :

Subject: [Boost-users] Boost.Preprocessor: expansion stops, result is further expandable
From: Roman Neuhauser (neuhauser_at_[hidden])
Date: 2011-06-18 20:37:23


Hello,

I'd like to thank everybody involved in creation of Boost.Preprocessor
for this cool piece of software, it does wonders.

I have a possibly naive question (I'm an autodidact) which involves
Boost.PP. I have stumbled upon strange behavior where the preprocessor
stops expanding but the output expands further if fed to the
preprocessor again.

Given these directives:

#include <boost/preprocessor.hpp>
#
#define DAPHP_REGISTER_CLASS(class_, props) \
  CXXEXT_REGISTER_CLASS( \
    class_ \
  , BOOST_PP_SEQ_TRANSFORM(DAPHP_MAKE_PROPERTY, ~, props) \
  )
#
#define DAPHP_MAKE_PROPERTY(_, __, name) \
  (name, IS_LONG, 0)
#
#define CXXEXT_REGISTER_CLASS(class_, props) \
  object< class_ >::register_(); \
  CXXEXT_DECLARE_PROPERTIES(class_, props)
#
#define CXXEXT_DECLARE_PROPERTIES(class_, props) \
  BOOST_PP_SEQ_FOR_EACH( \
    CXXEXT_DECLARE_PROPERTY_SEQ \
  , ~ \
  , BOOST_PP_SEQ_TRANSFORM(CXXEXT_PROPERTY_ADD_CLASS, class_, props) \
  )
#
#define CXXEXT_PROPERTY_ADD_CLASS(_, class_, prop) \
  BOOST_PP_ARRAY_DATA(BOOST_PP_ARRAY_PUSH_FRONT((3, prop), class_))
#
#define CXXEXT_DECLARE_PROPERTY_SEQ(_, __, elem) \
  BOOST_PP_EXPAND(CXXEXT_DECLARE_PROPERTY elem)
#
#define CXXEXT_DECLARE_PROPERTY(native_type, name, ztype_, default_) \
  object< native_type >::declare_property( \
    ZEND_ACC_PUBLIC \
  , ztype_ \
  , BOOST_PP_STRINGIZE(name) \
  , default_ \
  );
#
#define DAPHP_PROPS_DATE (year) (month) (day)

This:

DAPHP_REGISTER_CLASS(DapiDate, DAPHP_PROPS_DATE)

Expands to (newlines added):

object< DapiDate >::register_();
 object< DapiDate >::declare_property( ZEND_ACC_PUBLIC , IS_LONG , "year" , 0 );
 object< DapiDate >::declare_property( ZEND_ACC_PUBLIC , IS_LONG , "month" , 0 );
 object< DapiDate >::declare_property( ZEND_ACC_PUBLIC , IS_LONG , "day" , 0 );

With these definitions added to the mix:

#define DAPHP_REGISTER_CLASSES(classes) \
  BOOST_PP_SEQ_FOR_EACH( \
    DAPHP_REGISTER_CLASS_SEQ \
  , ~ \
  , classes \
  )
#
#define DAPHP_REGISTER_CLASS_SEQ(_, __, classprops) \
  DAPHP_REGISTER_CLASS( \
    BOOST_PP_TUPLE_ELEM(2, 0, classprops) \
  , BOOST_PP_TUPLE_ELEM(2, 1, classprops) \
  )

This:

DAPHP_REGISTER_CLASSES(
  ((DapiDate, DAPHP_PROPS_DATE))
)

Expands to (newlines added):

object< DapiDate >::register_();
BOOST_PP_SEQ_FOR_EACH(
  CXXEXT_DECLARE_PROPERTY_SEQ
, ~
, ((DapiDate, year, IS_LONG, 0))
  ((DapiDate, month, IS_LONG, 0))
  ((DapiDate, day, IS_LONG, 0))
)

Which is an intermediate expansion of the above listed
DAPHP_REGISTER_CLASS(DapiDate, DAPHP_PROPS_DATE).

g++ 4.5.0 (MinGW) and MSVC 9 Express behave the same, which makes me
believe this is a PEBKAC, but I just don't see it.

Why doesn't DAPHP_REGISTER_CLASSES expand all the way as
DAPHP_REGISTER_CLASS does? Please enlighten me.

-- 
roman

Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net