Boost logo

Boost :

Subject: Re: [boost] [geometry] view_as concept casting
From: David Abrahams (dave_at_[hidden])
Date: 2009-01-09 05:47:17

on Thu Jan 08 2009, "Simonson, Lucanus J" <> wrote:

>>> Barend wrote:
>>>> Furthermore, you mention: "concept checking boilerplate around bool
>>>> return type goes here". We've encountered problems with the concept
>>>> checking on return types. The combination of BCCL and overloads based on
>>>> SFINAE gives compiler problems here. We therefore use
>>>> BOOST_CONCEPT_REQUIRES instead of _ASSERT in such cases.
>>>Simonson, Lucanus J wrote:
>>> What compiler problems specifically?
>>> I don't use BCCL for concept checking, and should have said SFINAE
> meta->>programming boilerplate instead.
> Barend wrote:
>>Compiler problems: that it fails to specializes the function as soon as
>>the BCCL check is there. That is related to the SFINAE overloads. Cannot
>>reproduce it literally and it was also compiler dependant. But if the
>>BOOST*ASSERT was removed they were gone. It might also be solved by
>>using tag dispatchment suggested by Dave, I'll look to that.
> I had my basic generic geometry API fully implemented using tag
> dispatching and was very happy with it, until I eliminated the broken
> semantics of geometry concept inheritance

Umm, yes, inheritance doesn't work. However, concept refinement *does*

> and lost all of the polymorphism of geometry concept type that
> provided. It became very obvious that tag dispatching had its
> shortcomings when I was implementing the assign() function.
> //assigns any B type object to an object of type A
> template <typename A, typename B>
> A& assign(A& a, const B& b) {
> assign_dispatch(a, lookup_tag<A>::type(),
> b, lookup_tag<B>::type());
> }
> You can assign a rectangle to a polygon but not the other way around.

That's the classic OOP geometry modeling pitfall (i.e. the binary method
problem), but I don't see why it should be a problem with GP.

> You can assign a polygon to a polygon with holes, but not the other
> way around. It turns out that roughly half the possible combinations
> of types


> that could be arguments to assign were legal, meaning I had
> O(n^2) assign_dispatch functions to write.

I don't see it.

> This is intolerable
> because the number of types can be expected to increase over time, and
> increasing effort to add each type into the system would stunt the
> growth of the library over time. Instead I wrote O(n) assign
> functions that were based on SFINAE and used static polymorphism
> between different concepts to achieve my aim. A rectangle can model
> the read only polygon concept

Oh, but once you introduce immutable shapes you can no longer
claim that concept refinement isn't appropriate for modeling geometry.
It's just that you had the wrong hierarchy before.

                                               +--- Rectangle <- Square
                              +-- Polygon <--+
                             / \
Regular <-- HoleyPolygon <--+ +--- MutablePolygon
                              +--- MutableHoleyPolygon

Wow, Polygons are even Assignable! In fact, that B refines A *almost
never* means that you can assign a B into an A. Consider Field and
Vector Space.

I don't see any problems; just tag dispatch based on the concept modeled
by the LHS. Assign for Polygons can forego asking about the number of
RHS holes, assign for Rectangles can forego asking how many points there
are, and assign for Squares can forego asking for one of the side
lengths. What am I missing here?

> //assigns any type B that can model a read only polygon to A
> template <typename A, typename B>
> typename boost::enable_if<
> typename boost::mpl::and<
> typename is_mutable_polygon<A>::type,
> typename is_viewable_as_polygon<B>::type>::type,
> A>::type &
> assign(A& a, const B& b) { ... }
> //further overloads of assign are possible with SFINAE
> We need more than just overloading of generic functions based on
> conceptual type to implement a generic geometry library, we need
> static polymorphism.

I'm sorry, but that doesn't make any sense to me. One of the big
selling points of GP is that you *don't* lose static polymorphism. You
certainly don't lose any type information by tag dispatching.

> I'm just completed a release of my library that uses SFINAE
> overloading for the API. I wouldn't want to try to go back to tag
> dispatching.

Not gettin' it.

Dave Abrahams
BoostPro Computing

Boost list run by bdawes at, gregod at, cpdaniel at, john at