Boost logo

Boost Users :

Subject: Re: [Boost-users] [units][geometry] subtract_typeof_helper<> help!
From: Matthias Schabel (boost_at_[hidden])
Date: 2011-01-03 13:58:46


>>> Construction works here for me, but calculating distance does not.
>>> Because distance behind the screens takes the square root, after
>>> squaring. This requires thorough integration with Boost.Units at
>>> those places, which is not planned.
>>
>> I understand that integrations with Boost.Units is not planned and
>> even not desirable.
>> But making the implicit assumption that
>> typeof(sqrt(s)) == typeof(s) or that typeof(s*s)==type(s)
>> makes it incompatible with Boost.units. Those assumptions are good as
>> defaults but there should be a way to tell Boost.Geometry that
>> sometimes it is not the case.
>
> I took a stab at a generic solution to this problem of units and data types in a geometry library with Polygon. My coordinate_traits defines a distance time, area type etc. I then look up what data type to use for the return value of a distance or area calculation. Because it is a point of customization the user can specify data types with assoicated Boost.Units. My main concern was overflow at the time, but I think having a point of customization (meta function that can be specialized) and using it consistently would allow a generic geometry library to interoperate with Boost.Units without needing to be integrated with Boost.Units. Generic programing should allow exactly these types of compatibility between libraries without directly coupling them. Is there any reason why this approach wouldn't work?

I agree - the general sloppiness in treating mathematical operators in libraries that are intended to generically support them for UDTs seems to be a widespread problem, even within Boost. For example, std::complex (which "circumvents" the problem by disallowing UDT value types) defines

template<class T> complex<T> operator/(const complex<T>& lhs, const complex<T>& rhs);
 
However, even for a simple value type (e.g. integers - N.B. not int) this is not correct since integer/integer -> rational so this should really be

template<class T> complex<rational> operator*(const complex<integer>& lhs, const complex<integer>& rhs);

In general, anywhere that

template<class T> something<T> operator blah(const something<T>& lhs, const something<T>& rhs);

appears should look like (pseudocode)

template<class T> something<typeof(T blah T)> operator*(const something<T>& lhs, const something<T>& rhs);

instead. This requires a bit more care, but I think it is demonstrably the right thing to do and should probably be an expectation in Boost libraries. For example, I know that Boost.Quaternions, Boost.Octonions, and Boost.uBlas do not do the right thing in this context. It would also probably make sense to provide a Boost.Complex that allows UDTs and handles them correctly. It sounds like Boost.Geometry also does not correctly handle basic mathematical operators.

Matthias



Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net