Boost logo

Boost :

From: Vesa Karvonen (vesa_karvonen_at_[hidden])
Date: 2003-01-05 18:45:13


David Abrahams:
> > Paul Mensonides:
> > > The semantic change is that 'x' must not be a function-like macro.
                                           ^^^
[...]
>How can you use a macro which only tells you if a function-like macro
>is defined to tell you if an object-like macro is defined?

>If we could do that, couldn't you implement your original intended
>semantics?

Well, yes. It could be used for testing whether an object-like config macro
has been defined.

Actually, since it is not currently possible (portable) to pass around empty
parameters, it really shouldn't make much difference that function-like
macros may not be tested.

David Abrahams:
>Vesa Karvonen:
> > I got bored writing the "BOOL" versions of the macros, What are those,
>for us mortals, please?

I'm referring to a situation where a macro is either defined or not defined.
Such macros are quite heavily used for configuration purposes in many
places. For example, BOOST_NO_VOID_RETURNS is such a macro. It is defined,
as

  #define BOOST_NO_VOID_RETURNS

, if the compiler does not support void returns and otherwise it is not
defined at all.

Unfortunately, such config macros can not generally be used in conditions
for BOOST_PP_IF(), because it is impossible to directly test, in a macro,
whether an arbitrary macro is defined or not. As a workaround, one can make
a second macro definition based on whether the original config macro is
defined or not:

  #if defined(BOOST_NO_VOID_RETURNS)
  # define BOOST_NO_VOID_RETURNS_BOOL 1
  #else
  # define BOOST_NO_VOID_RETURNS_BOOL 0
  // ^^^^
  #endif

The "BOOL" version can then be used as a condition for BOOST_PP_IF(), for
instance.

However, ideally, on a perfect compiler, no config macros should be defined.
Having to define the "BOOL" macros, in order to make some programming tasks
easier, goes against the ideal. It is also quite tedious and verbose to have
to make such additional macro definitions.

The idea I had is to use BOOST_PP_IS_EMPTY() to avoid having to make the
above kind of additional "BOOL" macro definitions. I think that this goes
well with the spirit of Boost.Config.

As a purely syntactical example of using BOOST_PP_IS_EMPTY() consider the
following example from Boost.Python:

  // Specialization as a convenience for call and call_method
  template <>
  struct return_from_python<void>
  {
      typedef python::detail::returnable<void>::type result_type;

      result_type operator()(PyObject* x) const
      {
          (void_result_from_python)(x);
  # ifdef BOOST_NO_VOID_RETURNS
          return result_type();
  # endif
      }
  };

Using BOOST_PP_IS_EMPTY(), the above code can be written like this:

  // Specialization as a convenience for call and call_method
  template <>
  struct return_from_python<void>
  {
      typedef python::detail::returnable<void>::type result_type;

      result_type operator()(PyObject* x) const
      {
          (void_result_from_python)(x);

          BOOST_PP_EXPR_IF(BOOST_PP_IS_EMPTY(BOOST_NO_VOID_RETURNS),
                           return result_type();)
      }
  };

In this case the former code is shorter, but the possibility of doing the
latter might prove useful on other occasions. In particular, it would be
useful if you have a macro definition that depends on such a config macro.
In such a case, you would normally need to duplicate the macro definition:

  #if defined(CONFIG_MACRO)
  # define MACRO With a long *X* definition...
  #else
  # define MACRO With a long *Y* definition...
  #endif

With BOOST_PP_IS_EMPTY() the above could now be written like this:

  #define MACRO With a long
*BOOST_PP_IF(BOOST_PP_IS_EMPTY(CONFIG_MACRO,X,Y))* definition...

-Vesa Karvonen

_________________________________________________________________
Protect your PC - get McAfee.com VirusScan Online
http://clinic.mcafee.com/clinic/ibuy/campaign.asp?cid=3963


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