Boost logo

Geometry :

Subject: Re: [geometry] generic for_each and num proposal
From: Mats Taraldsvik (mats.taraldsvik_at_[hidden])
Date: 2013-07-29 13:41:18


Hi Barend,

On 07/28/2013 07:59 PM, Barend Gehrels wrote:
> Hi Mats,
>
> On 28-7-2013 12:23, Mats Taraldsvik wrote:
>> Hi,
>>
>> On 07/26/2013 11:54 PM, Michael Winkelmann wrote:
>>
>> It would be very useful to expand on the for_each algorithms.
>> However, as I understand the boost.geometry documentation and your
>> proposal, there is a subtle but important difference: the current
>> for_each_point algorithm work on a point _concept_, while your
>> for_each<point> algorithm work on a concrete point type (in this case
>> bg::model::d2::point_xy<double>.
>
> I don't see why this would not work for concepts?
>
>
>>
>> What if I used e.g. std::pair to represent points? I'd have to
>> remember the exact type used for points in the
>> polygon/ring/linestring/segment... I might have two polygons that
>> represents points in differents ways, and then I'd have to implement
>> the algorithm twice (for_each<bgm::d2::point_xy<double>> and
>> for_each<std::pair<double,double>>.
>>
>> I'm not sure if this is solvable in the generic case until we get
>> proper Concepts (lite), which, combined with generic lambdas would
>> make a concepts-based interface.
>
> 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! :)

Sorry if I come across as negative with my (hopefully constructive)
criticism, I'm trying not to be. :)

What I'm concerned with is the lambda argument to the for_each<*_tag>
algorithms. I'm not aware of a way to write a lamdba in terms of a
(geometry) concept, so they will be type-specific instead of
concept-specific. Which means they have to be tailored to the type of
the point/linestring/polygon etc. -- not the concept (which is ideal).

Consider a Polygon that has four points of different types:

bgm::d2::point_xy<double> point1
std::pair<double, double> point2
bgm::d2::point_xy<double> point3
std::pair<double, double> point4

How do you write the for_each<point_tag> where the lambda is able to
capture all four points? One could use a boost::variant or similar
structure to account for all point types, but it isn't ideal, is it?
(However, this might be the best solution for current C++(?))

Also, what if we decided to have some pre-defined lambdas/functions that
one could use with for_each<*_tag>? They'd have to be generic (i.e.
concepts-based) to be truly useful and universally applicable...

> What do you mean by Concept (lite)?

Concept[s] lite is the current proposal for constraining templates, and,
by extension, generic lambdas (c++14). It is planned as a TS in the
C++14 timeframe, as far as I know. The latest version is N3701, look at
the summer standards papers mailing [1] -- I think it is really
interesting, I think it is worth a look if you are not familiar with it
already.

I think this would allow the behaviour I am seeking:

for_each<point_tag>( aPolygon, [](PointConcept point)
{
     ...
});

or, a pre-defined function

auto point_to_wgs84(PointConcept point)
{
   ...
}

...

for_each<point_tag>(anotherPolygon, point_to_wgs84);

Where PointConcept is the boost geometry point concept. Thus, the actual
points in the polygon could be of different types, as long as the point
concept is satisfied, the lambda should work for all of them.

>
> Regards, Barend

[1] http://isocpp.org/blog/2013/07/summer-standards-papers-mailing-available

It's a future direction, I guess, but I thought it might be worth
pointing towards. :)

Mats

>
>
>
> _______________________________________________
> Geometry mailing list
> Geometry_at_[hidden]
> http://lists.boost.org/mailman/listinfo.cgi/geometry



Geometry list run by mateusz at loskot.net