Boost logo

Boost :

From: John Maddock (john_at_[hidden])
Date: 2006-05-24 05:41:54

AlisdairM wrote:
> The test is currently failing on the following line:
> ( BOOST_ROOT/boost/math/special_functions/hypot.hpp line 32)
> BOOST_ASSERT(std::numeric_limits<T>::is_specialized);
> I believe the problem is Borland's traditional bad handling of const
> parameters with templates. In the case of this test, T deduces as
> const double, so of course numeric limits is not specialized.
> I believe the workaround will be to detect Borland compiler, and do a
> remove_const on T for the whole function, or perhaps detect const and
> forward to an explicit call to the non-const function.
> A similar patch would be applied to:
> expm1.hpp
> log1p.hpp
> Are the library maintainers interested in supporting such a patch?
> Should we introduce the type_traits dependency (Checking for the
> Borland platform first?)
> Should we look to patch mainline, or 1.34 branch. The only active
> regression testing on Borland is on the 1.34 branch at the moment.

Can you test the following patch:

Index: ../../../boost/math/special_functions/hypot.hpp
RCS file: /cvsroot/boost/boost/boost/math/special_functions/hypot.hpp,v
retrieving revision 1.1
diff -r1.1 hypot.hpp
> #include <boost/type_traits/remove_const.hpp>
> #define BOOST_RCT(T) typename remove_const<T>::type
> #else
> #define BOOST_RCT(T) T
> #endif
< BOOST_STATIC_ASSERT(::std::numeric_limits<T>::is_specialized);

> BOOST_STATIC_ASSERT(::std::numeric_limits<BOOST_RCT(T)>::is_specialized);
<    BOOST_ASSERT(std::numeric_limits<T>::is_specialized);
>    BOOST_ASSERT(std::numeric_limits<BOOST_RCT(T)>::is_specialized);
<    if(std::numeric_limits<T>::has_infinity
<       && ((x == std::numeric_limits<T>::infinity())
<       || (y == std::numeric_limits<T>::infinity())))
<       return std::numeric_limits<T>::infinity();
>    if(std::numeric_limits<BOOST_RCT(T)>::has_infinity
>       && ((x == std::numeric_limits<BOOST_RCT(T)>::infinity())
>       || (y == std::numeric_limits<BOOST_RCT(T)>::infinity())))
>       return std::numeric_limits<BOOST_RCT(T)>::infinity();
<    T safe_upper = (std::sqrt)((std::numeric_limits<T>::max)()) / 2;
<    T safe_lower = (std::sqrt)((std::numeric_limits<T>::min)());
>    T safe_upper = (std::sqrt)((std::numeric_limits<BOOST_RCT(T)>::max)()) 
> / 2;
>    T safe_lower = (std::sqrt)((std::numeric_limits<BOOST_RCT(T)>::min)());
> #undef BOOST_RCT
However, if T is const, then the code shouldn't compile since the parameters 
x and y are *written to*.
I've tested this with Borland 5.6.4, and it fixes the assertion, but the 
test fails for other reasons (looks like it's throwing an exception rather 
than returning infinity).  There are lot's of issues I have with Borland's 
math handling that make it quite a task to adequately support this platform 
sadly: for example, this failure 
seems to be infinity related again, and this one: 
is a known about bug in sinh/cosh/tanh in the std lib version used.
Anyway, if the above patch works OK with 5.8 please feel free to commit.

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