Boost logo

Boost :

From: Paul Mensonides (pmenso57_at_[hidden])
Date: 2002-04-10 16:45:17


> Sorry, I'm not good at divining the meaning of uncommented code. Could
> you please tell me what you're trying to illustrate below?

The purpose of the AUX_MY_CONSTRUCT_GET macro is to be expanded with various
numbers from a low bound to an upper bound. I borrowed the name
'AUX_MY_CONSTRUCT_GET' from a previous example. The macros used to perform the
iteration are in effect recursive. I.e. (to make a long story short):

#define EXPAND_0(NAME) NAME(0)
#define EXPAND_1(NAME) EXPAND_0(NAME) NAME(1)
#define EXPAND_2(NAME) EXPAND_1(NAME) NAME(2)

// etc. minus all the miscellaneous options.

This type of this kills the performance of some preprocessors. Especially when
the macro that is passed does the same thing again--like
BOOST_MY_LIBRARY_PP_PARAMS in the example. My point is that the top level of
recursion can be performed much more efficiently with linearization then it can
with recursion. I'll make some comments...

'make.h' expands a macro named 'MACRO' with a number of in the range of
LOWER_BOUND to UPPER_BOUND (inclusive). It does this in a linear way.

> > // make.h
> >

This is a safeguard for UPPER_BOUND not being set:

> > #ifndef UPPER_BOUND
> > #error UPPER_BOUND is not set
> > #endif

This is a default value if LOWER_BOUND is not set:

> > #ifndef LOWER_BOUND
> > #define LOWER_BOUND 1
> > #endif
> >

This is a utility to save typing. :)

> > #define IS_RANGE(N) LOWER_BOUND <= N && UPPER_BOUND >= N

The following checks to see if some number N is in the range specified by
LOWER_BOUND and UPPER_BOUND. If it is, it expands MACRO with that number.

> > #if RANGE(0)
> > MACRO(0)
> > #endif
> > #if RANGE(1)
> > MACRO(1)
> > #endif
> > #if RANGE(2)
> > MACRO(2)
> > #endif
> > // etc.
> >
> > // sample.h

Set upper and lower bounds:

> > #define LOWER_BOUND 0
> > #define UPPER_BOUND 15

Sample macro to be expanded:

> > #define AUX_MY_CONSTRUCT_GET(i) \
> > template< BOOST_MY_LIBRARY_PP_PARAMS(i, typename T) > \
> > struct my_construct { /* more stuff */ }; \
> > /**/
> >

Define MACRO to be AUX_MY_CONSTRUCT_GET. This should be changed to:
#define MACRO(N) AUX_MY_CONSTRUCT_GET(N)

> > #define MACRO AUX_MY_CONSTRUCT_GET

'call' the expansion header...

> > #include "make.h"

finally, undefine everything...

> > #undef LOWER_BOUND
> > #undef UPPER_BOUND
> > #undef AUX_MY_CONSTRUCT_GET
> > #undef MACRO
> >
> > Paul Mensonides

There are several positives of this approach. It is significantly more
efficient than the 'recursive' version. Each expansion of AUX_MY_CONSTRUCT_GET
is on a separate line, so if you preprocess the file in a separate step, you can
get decent error messages.

Paul Mensonides


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