Boost logo

Boost :

From: Simonson, Lucanus J (lucanus.j.simonson_at_[hidden])
Date: 2007-10-05 13:46:00


Joel wrote:
>That's very good. I'm not quite sure about inheritance though.

>> P.S. my point2d data structure is a class encapsulated array of size
2.
>> You can override it with your own, of course, through the template
>> inheritance generic interface.

>With the restriction that it has to be indexable by a runtime int?
>That is a severely limited concept of a point, I would say. And,
>again, I find the need for inheritance dubious. Inheritance gives
>you tight coupling. Something that you'd want to avoid when
>adopting a 3rd party type. It is possible to adopt a 2d-point
>from library A and library B without ever touching them. That's
>the very essence of generic programming.

I put a lot of thought into the implications of inheritance, believe me.
There is no restrition that it has to be indexable by a runtime int.
Your point2d data type can and should be something like:
struct MyLegacyPoint2D {
        int x;
        int y;
};
Your concept map to my point2d concept class would look like:
template <>
class PointConceptMap<MyLegacyPoint2D> {
        static inline int
        PointGet(const MyLegacyPoint2D& t, Orientation2D orient)
        { return predicated_value(orient == HORIZONTAL, t.x, t.y); }

        static inline void
        PointSet(MyLegacyPoint2D& t, Orientation2D orient, int value)
        { predicated_assign(orient == HORIZONTAL, t.x, t.y, value); }

        static inline MyLegacyPoint2D PointConstruct(int xval, int
yval) {
                MyLegacyPoint2D tmp;
                tmp.x = xval; tmp.y = yval;
                return tmp;
        }
privte:
        PointConceptMap();
};

Your usage of your data type with my point concept would look like

MyLegacyPoint2D pt;
point_concept<MyLegacyPoint2D>& ptconcept = point_concept::mimic(pt);
point_concept<point2d_data> gtlptconcept(10, 20);
ptconcept.set(HORIZONTAL, 10);
ptconcept.set(VERTICAL, 20);
assert(ptconcept == gtlptconcept);

You use my concept class's == operator with your data type to compare it
to my data type. I have dozens of point2d concept class member
functions that become available for you to use with your data type to
interact with my data type.

All this seems like overkill with simple point2d data types but when you
have polygons that are sequences of vertices it becomes a Rosetta stone
of type inter-compatibility and a mechanism for getting legacy data in
and out of algorithms in a generic, zero cost of abstraction way that is
minimal effort and very productive (not error prone.) When you realize
that my Polygon concept class uses my Point concept class to interact
with its vertices the whole picture suddenly becomes clear. Sometimes
it is useful to have a polygon that is a linked list of points.
Sometimes it is useful to have a vector, sometime it is useful to have a
compressed storage for polygon data. The polygon concept class is the
glue that can really tie everything together and make it all work
together as smooth as butter.

By the way if you have a 3D point you can view it as a 2D point (because
conceptually it is a 2D point with extra semantics.) I do that all the
time, and use it to refactor my higher dimension code instead of
templating the dimensionality.

It might have been better if I called it the Geometry Concepts Library,
since the term template is too *ahem* generic.

Lucanus Simonson


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