|
Boost : |
Subject: Re: [boost] [geometry] view_as concept casting
From: Simonson, Lucanus J (lucanus.j.simonson_at_[hidden])
Date: 2009-01-08 18:42:32
>> 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 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. 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. 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, for instance.
//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 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.
Regards,
Luke
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk