Boost logo

Geometry :

Subject: Re: [geometry] generic for_each + num proposal
From: Barend Gehrels (barend_at_[hidden])
Date: 2013-07-31 11:14:00

Hi Micha,

On 30-7-2013 15:19, Michael Winkelmann wrote:
> Hi Barend + Mats,
> thanks for your replies.
> On 29.07.2013 18:00, geometry-request_at_[hidden] wrote:
>> About num_points, yes, that is also good but... num_points and
>> num_interior_rings are prescribed by OGC (which we follow). If we leave
>> that (we could), then I would propose "size" instead, like STL does. The
>> num_interior_ring does have a tweak - you don't really know this... You
>> might say it is num<rings> - 1, but in case of multi-polygons that is
>> not valid.
> I don't know if the OGC standard prescribes how the num algorithm
> needs to be implemented,
> but I think if there is a generic solution, num_points and
> num_interior_rings might just be template specializations of the
> generic version (of point_tag and interior_rings_tag, respectively).
> How would you use the "size" e.g. in a ring? size<point>(myRing) or
> myRing.size()?

size<point_tag>(myRing), using the concept, because we cannot use any
methods on a ring

interior_rings_tag is indeed a solution (until now we don't have it, but
that is no problem)

>> Hi Mats, On 28-7-2013 12:23, Mats Taraldsvik wrote:
>>> OK now I see what you mean. The proposal has probably to be read as:
>>> size_t a = num<ring*_tag*>(myPolygon); // Returns number of rings in
>>> polygon
>>> size_t b = num<segment*_tag*>(myRing); // Returns number of segments
>>> in ring
>>> size_t c = num<polygon*_tag*>(myPolygon); // Should return 1
>>> The tag's are mostly used internally, if used externally, they could
>>> (maybe) be namespaced e.g.
>>> size_t a = num<*geometry_type::*ring>(myPolygon); // Returns number of
>>> rings in polygon
>>> (don't know if this name is appropriate, just an idea)
>> I'm sorry, I could have been more clear (and I might simply be wrong :)
>> ). I think the num-part of the proposal is fine with *_tag as template
>> arguments. As long as the actual algorithm is written with the
>> operations required by the point concept, it should work for every type
>> that satisfies the point concept. And it is very useful indeed! :)
> Yeah, it should definitely work when using tags since you can register
> your pair-point type and
> access its components by using bg::get<n> and bg::set<n> (like in
> Barends examples).
> As Mats mentioned, Concept lite and generic lambda are expected to be
> in the C++14 standard.
> But instead of a generic lambda, one could use the old-fashioned version:
> struct RingOperation
> {
> template<class T>
> void operator()(const T& _t) { ... }
> };
> for_each<ring>(myRing,RingOperation);
> ... which lacks of course readability but it should work if T and ring
> are the same (could be checked by using std::is_same<T,ring>)

Right, in this variant you don't have to specify the template-argument
in RingOperation.

> Constness is another issue to be considered:
> If I use for_each<segment>(myRing,...) (not referring_segment!),
> segment and input geometry should be const and only be const (since
> the current segment is actually a copy).
> whereas when using for_each<point>(myRing,...) there needs to be a
> const and mutable version.

And rings?
By the way, if we have the interior_ring_tag, we can also use
for_each<interior_ring_tag> to walk over interior-rings only (so then we
need an exterior_ring tag too).

Regards, Barend

Geometry list run by mateusz at