Subject: [ggl] implementation constructs and their names
From: Barend Gehrels (Barend.Gehrels)
Date: 2009-05-29 14:17:29
This subject is rather technical on implementation details.
For several time I'm thinking about the following. Algorithms are (or
should be) following the same pattern:
1) there is an algorithm
2) which gets the geometry-tag and calls a static method from the
tag-dispatching structure specialized for that geometry
3) which forwards its call to a certain implementation
This was not always like this because last November or so we moved from
SFINAE to tag-dispatching, a happy choice with all benefits. Therefore
some implementations are different:
- some are functions (called by dispatch-s struct)
- some are struct's with a static inline call (dispatch can then derive
However, struct's are more generic: when implementing/updating the
multi-versions, I change them to struct's because they can be
implemented for multi-geometries in a very generic way.
So we have (e.g. area)
1) the function area
2) the dispatch structure area with specializations, having method
3) several implementation struct's having method "calculate", dispatches
are derived from them (in case of area some are derived the structs,
some still call the functions)
and for multi:
4) the dispatch structure area specialized for multi-polygon, derived from:
5) the more generic structure "multi_sum" with a policy, where the
implementation struct of 3) perfectly serves as its policy
The "multi_sum" is also used in the length and perimeter algorithms of
the multi-geometries. (Side topic: could be even more generic using
std::plus instead of just adding. However e.g. products are probably
So today I moved an algorithm "remove_holes_if" (sie-topic: the name
"hole" is an error, will be renamed to "remove_interior_rings_if") from
a project I'm dowing to the GGL and its follows this structure. It is
committed, you can see that it is all syntactic sugar around
std::remove_if and the erase-remove idiom. However, the name "calculate"
was not so appropriate here (it removes holes based on a user-specified
condition). So I toke "modify" as the struct-method. The multi-polygon
uses a re-usable version of this which I called "modify_with_predicate"
and this might be reused later for other algorithms.
So this general pattern is probably OK and generic and is nicely used in
However (HERE the question is): I'm doubting about the name. I like
boost::mpl which has naming conventions: "type", "value", "type::value"
and "apply". Using these conventions the (implementation) struct's can
be used as building blocks and combined together. So I would like to
have something like this in these implementation structs. But mpl are
meta-functions, no callable functions. So we have to invent something, like:
- "run" (as in arithmetic.hpp) as a method which can do something but
also calculate something and return the result. The name "run" does
suggest that something is happening. But for e.g. "num_points",
calculating the number of points, it does not sound too logical to me
- "calculate" is appropriate for calculations, but often nothing is
calculated -> then something is done (like removing holes). OTOH it is
appropriate for e.g. intersections (which are "calculated' or "determined")
- "apply" (also here) can be used for anything but also here, like
"run", is apply appropriate for returning the area-sum?
- what if something is "determined", e.g. disjointness or if geometries
are spatially equal?
So we can take one or we can take several, based on circumstances, and
- "calculate" for everything returning an arithmetic value
- "modify" for everything doing something on geometries
- "determine" for everying returning a boolean
However, this also has disadvantages, there will be unclear and/or
additional cases (what about "parse").
So I'm still doubting but think we should have one thing. What is then
the most appropriate?
Any comments, answers or opinions are appreciated.
Geometry list run by mateusz at loskot.net