Boost logo

Boost :

From: Fernando Cacciola (fernando_cacciola_at_[hidden])
Date: 2008-05-18 16:59:06


Hi Luke,

I'm only now having some time to follow the GTL evolution...

> The user must register their type as a polygon set type:
>
> template <>
> geometry_traits<std::list<UserPolygonType> > { typedef
> polygon_set_concept geometry_concept; };
>
This is probably explained somewhere but, could you state what a

geometry_traits<T>::geometry_concept

is?

> Then the user can use their type along with the library provided type
> to perform set operations through the intuitively overridden c++
> logical operators & | ^ -.
>
> template <typename geometry_type_1, typename geometry_type_2>
> polygon_set_view operator&(const geometry_type_1& geo1,
> const geometry_type_2& geo2) {
> ...tag dispatching and so forth... }
>
>
tag dispatching (used in this way) won't prevent ambiguity in the overload
resolution, so I don't think you should have operators taking just any
types.

> I also provide some Boolean logic capabilities to move flow control
> into functional code.
>
> template <typename geometry_type>
> polygon_set_view operator&(const geometry_type& geo, bool
> condition) { if(condition) return polygon_set_view(geo); }
>
else return polygon_set_view();

I presume?

> to the user to write code that looks like the following:
>
> std::list<UserPolygonType>* do_something_complex(bool condition1,
> bool condition2)
> {
> std::list<UserPolygonType>* resultPolygons =
> new std::list<UserPolygonType>;
> std::vector<rectangle_data> input1;
> initialize1(input1);
> std::vector<rectangle_data> input2;
> initialize2(input2);
>
> //if both condition1 and condition2 are true return the merged
> //result of the subtraction of input2 from input1
> //stored as UserPolygonType into resultPolygons
> //if condition1 is true and condition2 is false return input1
> //merged and stored as UserPolygonType into resultPolygons
> //if condition1 is false return empty resultPolygons
> resultPolygons |= ((input1 & condition1) - (input2 &
> condition2));
> //legacy application puts onus on caller to delete
> resultPolygons
> return resultPolygons;
> }
>
Apart from the fact that the operator declaration needs sme work to avoid
ambiguity, this is nice.

> Note that I'm using a polygon_set_view to provide lazy evaluation of
> the scanline algorithm when chaining operations. A polygon_set_view
> models
> the polygon_set_concept on the lazily produced result of the
> operation.
>
I would like better if the library used a general expression templates
framework instead of a custom mechanism so it can be used in much more than
just polygon set operations. But then of course, does boost has any of that
already?

> Because evaluation is lazy, the result of a Boolean operation should
> be stored to a polygon_set data structure before the arguments go out
> of
> scope or are deleted to ensure correct execution.
>
> Checking and proper
> generation of exceptions for such cases should be provided by the
> view. Modification of an argument after creating a view from it and
> before evaluating the view would be an undetectable user error.
>

How is this ensured in your proposal?
I'm inclined to think that the only reliable way to do this is to store the
operands via shared_ptr.

>
> This proposed API is the most concise and intuitive way I can think of
> to provide these algorithms to the library user.
>
Do you mean the operator syntax or the lazy evaluation?
I don't care for the former, but I certainly do for the latter, and to a
broader extent.

Best

Fernando Cacciola


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk