Boost logo

Boost :

From: Vesa Karvonen (vesa.karvonen_at_[hidden])
Date: 2001-12-03 07:23:51


From: "Daryle Walker" <darylew_at_[hidden]>
> If you look at the dlw_int.zip library in the vault, you'd note that the
> test files use a lot of repetitious macro functions. How could I use the
> new Preprocessor library to compact the macros?

First of all, the CodeWarrior compiler does not pass the preprocessor library
unit test. So, if you are using CW on Mac, then...

The following is a reimplementation of the PRIVATE_FIT_TESTS() macro using the
preprocessor library. It differs slightly from the original. The difference is
that "v >>= 1;" is done also on the last iteration, but as far as I understand
the test, it should not matter. I did not analyze the tests (at all), so the
tests could perhaps be simplified so that they can be generated using less
code.

#define PRIVATE_FIT_TEST(I, TEM_TYP_VAL)\
  BOOST_TEST(BOOST_PREPROCESSOR_TUPLE_ELEM(3,0,TEM_TYP_VAL) <\
  BOOST_PREPROCESSOR_SUB(32,I) > ::
BOOST_PREPROCESSOR_TUPLE_ELEM(3,1,TEM_TYP_VAL)\
  ( BOOST_PREPROCESSOR_TUPLE_ELEM(3,2,TEM_TYP_VAL)) ==\
  BOOST_PREPROCESSOR_TUPLE_ELEM(3,2,TEM_TYP_VAL)); v >>= 1;

#define PRIVATE_FIT_TESTS(Template, Type, ValType, InitVal)\
  do {\
    ValType v = InitVal ;\
    BOOST_PREPROCESSOR_REPEAT(33,PRIVATE_FIT_TEST,(Template,Type,v))\
  } while ( false )

Despite the long BOOST_PREPROCESSOR prefixes, the above is clearly over 3
times smaller than the original. Since the test code has the same repetition
patterns over and over again, I think that a considerably higher "compression
ratio" can be achieved. This can be done by implementing appropriate
"higher-order" (== macro that takes macro(s) as parameter(s)) test repetition
macros.

So, I hope that the above example gets you started. The key thing to note is
that you can use tuples to pass multiple arguments (up to 8 is supported). You
can also use the arithmetic operations to compute indices. Hmm... Actually it
really shouldn't be important that the number passed as a template argument is
a single token. So, you can simplify the above to:

#define PRIVATE_FIT_TEST(I, TEM_TYP_VAL)\
  BOOST_TEST(BOOST_PREPROCESSOR_TUPLE_ELEM(3,0,TEM_TYP_VAL) <\
  32-I > :: BOOST_PREPROCESSOR_TUPLE_ELEM(3,1,TEM_TYP_VAL)\
  ( BOOST_PREPROCESSOR_TUPLE_ELEM(3,2,TEM_TYP_VAL)) ==\
  BOOST_PREPROCESSOR_TUPLE_ELEM(3,2,TEM_TYP_VAL)); v >>= 1;


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