[intrusive] New failures on Tru64/CXX

Hello, recently intrusive started failing on Tru64/CXX with the following errors: cxx: Error: ../boost/intrusive/detail/utilities.hpp, line 543: incomplete type is not allowed (incompletetyp) const std::size_t value = (std::size_t)sqrt2_pow_max<sizeof(std::size_t)*CHAR_BIT>::value; ------------------------------------------^ cxx: Error: ../boost/intrusive/detail/utilities.hpp, line 544: incomplete type is not allowed (incompletetyp) const std::size_t pow = (std::size_t)sqrt2_pow_max<sizeof(std::size_t)*CHAR_BIT>::pow; ------------------------------------------^ The failure is caused by Tru64 being a 64 bit platform, but not having a long long integer type, because the compiler mode used is strict_ansi. Removing the #ifdef BOOST_HAS_LONG_LONG ... #endif in utilities.hpp, therefore enabling the code in between, fixes the error. AFAICT, what the code tries to do is provide precomputed values for some constants dependent on the size of size_t. It does this by trying to deduce the size of size_t from the definition of BOOST_HAS_LONG_LONG, which is not correlated in general. Can anybody think of an implementation for the following: template<std::size_t N> struct sqrt2_pow_max; template<> struct sqrt2_pow_max<sizeof(std::size_t)> { static const std::size_t value = ...; static const std::size_t pow = ...; }; providing the correct constants for value and pow, regardless of the bit size of size_t? (I don't know the formula used to compute the values of value and pow, hopefully Ion can provide those.) Regards, Markus

Markus Schöpflin wrote:
Hello,
recently intrusive started failing on Tru64/CXX with the following errors:
I noticed this this morning so I've uploaded this patch to SVN that activates specializations using enable_if. This seems to work on msvc-7.1, msvc-8.0, intel-9.1, gcc-4.1 and gcc-3.4 Can you check if this solves the problem? Thanks! Ion Index: C:/LocalSVN/boost/trunk/boost/intrusive/detail/utilities.hpp =================================================================== --- C:/LocalSVN/boost/trunk/boost/intrusive/detail/utilities.hpp (revision 41240) +++ C:/LocalSVN/boost/trunk/boost/intrusive/detail/utilities.hpp (working copy) @@ -515,33 +515,35 @@ return ((x & (x-1))!= 0) + floor_log2(x); } -template<std::size_t N> +template<class SizeType, std::size_t N> +struct numbits_eq +{ + static const bool value = sizeof(SizeType)*CHAR_BIT == N; +}; + +template<class SizeType, class Enabler = void > struct sqrt2_pow_max; -template<> -struct sqrt2_pow_max<32> +template <class SizeType> +struct sqrt2_pow_max<SizeType, typename enable_if< numbits_eq<SizeType, 32> >::type> { static const boost::uint32_t value = 0xb504f334; static const std::size_t pow = 31; }; -#ifdef BOOST_HAS_LONG_LONG - -template<> -struct sqrt2_pow_max<64> +template <class SizeType> +struct sqrt2_pow_max<SizeType, typename enable_if< numbits_eq<SizeType, 64> >::type> { static const boost::uint64_t value = 0xb504f333f9de6484ull; static const std::size_t pow = 63; }; -#endif - // Returns floor(pow(sqrt(2), x * 2 + 1)). // Defined for X from 0 up to the number of bits in size_t minus 1. inline std::size_t sqrt2_pow_2xplus1 (std::size_t x) { - const std::size_t value = (std::size_t)sqrt2_pow_max<sizeof(std::size_t)*CHAR_BIT>::value; - const std::size_t pow = (std::size_t)sqrt2_pow_max<sizeof(std::size_t)*CHAR_BIT>::pow; + const std::size_t value = (std::size_t)sqrt2_pow_max<std::size_t>::value; + const std::size_t pow = (std::size_t)sqrt2_pow_max<std::size_t>::pow; return (value >> (pow - x)) + 1; }
participants (2)
-
Ion Gaztañaga
-
Markus Schöpflin