|
Boost : |
Subject: Re: [boost] A design for geometric objects
From: Simonson, Lucanus J (lucanus.j.simonson_at_[hidden])
Date: 2008-11-20 18:08:09
Luke wrote:
>> I was in the middle of typing up a proposal for what Bruno suggests, but >> had a different solution to knowing whether a specialization exists. My >>solution was simply to register the conceptual type of the object with a >>meta function, which indicates both that the corresponding traits should >>also be defined as well as an easy way to tell what conceptual type that >>object most closely models.
Bruno replied to Luke:
>Indeed it's another right approach I think, don't know either which
>one would be the best one.
After refactoring the majority of my library to use my approach I have come up with a rational for using the meta-function rather than inspecting the traits for the existence of a member that indicates that it has been specialized for a given type.
It is very convenient to define default traits that apply to any type T. This allows the user (and the library author) to conform the public interface of their classes to the default definition of a class that models the concept. A good example of this is the iterator traits, which default to look for value_type and so forth, but can be specialized if needed.
In my library, I want any vector of objects that model rectangle, for instance, can be treated as an aggregation of manhattan polygonal data and serve as a valid argument to functions that operate on aggregations of geometry data, such as boolean operations. I also want to allow individual polygons or rectangles to behave as read only aggregations of geometry data. By using some meta-function based indirection I implemented a default definition of the traits for aggregations of geometry data that is applicable to any object that models rectangle, polygon, or list/vector of such. In this way, a user need only define the traits for their polygon type and immediately get access to functions that operate on collections of their polygon through the library API. I can then use other meta functions to protect the declarations of those functions using SFINAE rather than depend on a specialization of the traits being defined for every combination of container and geometry data type.
Assuming UserPolygon has specialized the polygon traits the following syntax is legal.
UserPolygon p;
std::list<UserPolygon> plist1, plist2;
// self assignment OR of result of an AND operation between
// a polygon and a list of polygons
plist1 += P * plist2;
//assign the result of bloating by three the XOR of a polygon and
//a list of polygons
assign(plist1, (p ^ plist2) + 3);
Note that the operator functions are fully protected by SFINAE to prevent collision with other generic operator declarations.
It is much more intuitive to a user to define the traits for their polygon and have all higher order functionality that depends on their polygon type work out-of-the-box rather than have to define additional traits for higher order concepts. Is there a way that can be accomplished without default definitions for traits?
Regards,
Luke
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk