Boost logo

Boost :

From: Arkadiy Vertleyb (vertleyb_at_[hidden])
Date: 2005-02-27 10:31:39


Hi all,

If one needs to manage a lot of PP code, some code structuring technique
might be helpful. So, how about the OO? The example below demonstrates
this techinique with the canonical shapes example.

An object is represented as a PP sequence of properties. The head of the
sequence contains the "class name" and is used for dispatching.

I believe this proved very useful in the BOOST_TYPEOF project where we
polymorphicaly treat type, integral, and template template parameters.

Comments?

Regards,
Arkadiy

--
#include <boost/preprocessor/seq/transform.hpp>
#include <boost/preprocessor/seq/enum.hpp>
#include <boost/preprocessor/seq/cat.hpp>
#include <boost/lambda/lambda.hpp>
#include <algorithm>
#include <iostream>
//
    #define VIRTUAL(Fname, This) BOOST_PP_SEQ_CAT(\
        (BOOST_PP_SEQ_HEAD(This))(_)(Fname))
//
    #define CIRCLE(r) (CIRCLE)(r)
    #define CIRCLE_RADIUS(This)\
        BOOST_PP_SEQ_ELEM(1, This)
    #define CIRCLE_AREA(This)\
        2 * 3.14159 * CIRCLE_RADIUS(This)
//
    #define RECTANGLE(h, w) (RECTANGLE)(h)(w)
    #define RECTANGLE_HIGHT(This)\
        BOOST_PP_SEQ_ELEM(1, This)
    #define RECTANGLE_WIDTH(This)\
        BOOST_PP_SEQ_ELEM(2, This)
    #define RECTANGLE_AREA(This)\
        RECTANGLE_HIGHT(This) * RECTANGLE_WIDTH(This)
//
    #define SQUARE(x) (SQUARE)(x)
    #define SQUARE_SIDE(This)\
        BOOST_PP_SEQ_ELEM(1, This)
    #define SQUARE_AREA(This)\
        SQUARE_SIDE(This) * SQUARE_SIDE(This)
//
    #define MY_SHAPES\
        (CIRCLE(5))\
        (RECTANGLE(3, 4))\
        (CIRCLE(3))\
        (SQUARE(3))\
        (SQUARE(5))\
        (RECTANGLE(2, 6))
    #define ENUM_AREAS(shapes)\
        BOOST_PP_SEQ_ENUM(BOOST_PP_SEQ_TRANSFORM(OP, ~, shapes))
    #define OP(s, data, elem)\
        VIRTUAL(AREA, elem)(elem)
    double MyAreas[] = {
        ENUM_AREAS(MY_SHAPES)
    };
//
int main()
{
    using namespace std;
    using namespace boost::lambda;
    for_each(
        MyAreas,
        MyAreas + sizeof(MyAreas)/sizeof(MyAreas[0]),
        cout << _1 << "\n");
    return 0;
}

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