Boost logo

Boost :

From: Atry (pop.atry_at_[hidden])
Date: 2007-04-14 03:10:42


As we known, there is a preprocess metaprogramming library in boost, but it is not flexible enough. we are unable to define an custom preprocess loop(something like #for or #while ?), and we are also unable to use recursion.

I have an idea to do that, C/C++ allows recursion of #include, so we can put the codes we want to evaluate repeatedly to a head, and include itself depends on a preprocess condition.

But if we wrote code below, we would meet a error of macro redefinition.
/**** foo.hpp ****/
#if FOO < 10
// do something with I
# define FOO FOO + 1
# include "foo.hpp"
#endif
/**** foo.hpp ****/

/**** bar.hpp ****/
#define FOO 0
#include "foo.hpp"
/**** bar.hpp ****/

The problem is that an macro must not depends on itself. Thus, to change a preprocess variant, I use a bit of #if to transfer value of a macro to some temporary macro. see my code below:

/**** begin_set_value.hpp ****/
#if (BOOST_VPP_VALUE & (1 << 0)) == 0
#define BOOST_VPP_TEMPORARY_BIT_0 0
#else
#define BOOST_VPP_TEMPORARY_BIT_0 1
#endif
#if (BOOST_VPP_VALUE & (1 << 1)) == 0
#define BOOST_VPP_TEMPORARY_BIT_1 0
#else
#define BOOST_VPP_TEMPORARY_BIT_1 1
#endif
/* ... */
#if (BOOST_VPP_VALUE & (1 << 30)) == 0
#define BOOST_VPP_TEMPORARY_BIT_30 0
#else
#define BOOST_VPP_TEMPORARY_BIT_30 1
#endif
#if (BOOST_VPP_VALUE & (1 << 31)) == 0
#define BOOST_VPP_TEMPORARY_BIT_31 0
#else
#define BOOST_VPP_TEMPORARY_BIT_31 1
#endif

#undef BOOST_VPP_VALUE

#define BOOST_VPP_VALUE \
    (BOOST_VPP_TEMPORARY_BIT_0 << 0 ) \
    + (BOOST_VPP_TEMPORARY_BIT_1 << 1 ) \
    + (BOOST_VPP_TEMPORARY_BIT_2 << 2 ) \
    + (BOOST_VPP_TEMPORARY_BIT_3 << 3 ) \
    /* ... */ \
    + (BOOST_VPP_TEMPORARY_BIT_29 << 29 ) \
    + (BOOST_VPP_TEMPORARY_BIT_30 << 30 ) \
    + (BOOST_VPP_TEMPORARY_BIT_31 << 31 ) \
    /*BOOST_VPP_VALUE*/
/**** begin_set_value.hpp ****/

Now, the BOOST_VPP_VALUE is depends on some of BOOST_VPP_TEMPORARY_BIT_n, and can be used to change the former macro:
#define FOO 0
#define BOOST_VPP_VALUE FOO
#include "begin_set_value.hpp"
#undef FOO
#define FOO (BOOST_VPP_VALUE + 1)

But, FOO depends on BOOST_VPP_TEMPORARY_BIT_ns, and can not be change again, the solution is that A must a variant depends on some other BIT_n definition instead of directly depends on BOOST_VPP_VALUE. Actually, I implements an variant stack to allocate and release these variant.

I think the concept of variable preprocess is useful, if Boost.Typeof or Boost.Bind use that, these code they need would be less than copying same codes.

I have upload a sample on vault, file name is variable_preprocess.zip.
http://boost-consulting.com/vault/index.php?&direction=0&order=&directory=Preprocessor%20Metaprogramming
http://boost-consulting.com/vault/index.php?action=downloadfile&filename=variable_preprocess.zip&directory=Preprocessor%20Metaprogramming&

All code is validated by wave, thank you for your attention.


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