type_traits changes break Boost.Python under IRIX

The recent changes to the type_traits library break our Boost.Python builds under IRIX, using the old MIPSpro 7.3.1 compiler. This compiler is based on EDG 238. The problem is illustrated by this simple piece of code: template <class T> struct is_signed_helper { static const bool value = (static_cast<T>(-1) < 0); }; % CC -n32 -mips4 -LANG:std -c foo.cpp cc-3314 CC: ERROR File = foo.cpp, Line = 4 The expression must have arithmetic, enum, or pointer type. static const bool value = (static_cast<T>(-1) < 0); ^ 1 error detected in the compilation of "foo.cpp". I tried several ideas for a workaround. The only one that worked in the end is the patch attached to this message. I know it is not pretty, but it has no effect on compilers other than EDG 238. I'd be happy to try other ideas, but all of Boost.Python compiles and runs with the patch. Unless someone else needs a more general fix (that works for user-defined types) I doubt the old compiler is worth more effort. Is the attached patch acceptable as a workaround? Cheers, Ralf Index: is_signed.hpp =================================================================== RCS file: /cvsroot/boost/boost/boost/type_traits/is_signed.hpp,v retrieving revision 1.1 diff -u -r1.1 is_signed.hpp --- is_signed.hpp 30 Jan 2005 15:47:45 -0000 1.1 +++ is_signed.hpp 2 Feb 2005 06:42:43 -0000 @@ -21,12 +21,35 @@ namespace detail{ +#if !(defined(__EDG_VERSION__) && __EDG_VERSION__ == 238) + template <class T> struct is_signed_helper { BOOST_STATIC_CONSTANT(bool, value = (static_cast<T>(-1) < 0)); }; +#else + +template <class T> +struct is_signed_helper; + +template <> struct is_signed_helper<char> { BOOST_STATIC_CONSTANT(bool, value = false); }; +template <> struct is_signed_helper<signed char> { BOOST_STATIC_CONSTANT(bool, value = true); }; +template <> struct is_signed_helper<unsigned char> { BOOST_STATIC_CONSTANT(bool, value = false); }; +template <> struct is_signed_helper<short> { BOOST_STATIC_CONSTANT(bool, value = true); }; +template <> struct is_signed_helper<unsigned short> { BOOST_STATIC_CONSTANT(bool, value = false); }; +template <> struct is_signed_helper<int> { BOOST_STATIC_CONSTANT(bool, value = true); }; +template <> struct is_signed_helper<unsigned int> { BOOST_STATIC_CONSTANT(bool, value = false); }; +template <> struct is_signed_helper<long> { BOOST_STATIC_CONSTANT(bool, value = true); }; +template <> struct is_signed_helper<unsigned long> { BOOST_STATIC_CONSTANT(bool, value = false); }; +template <> struct is_signed_helper<long long> { BOOST_STATIC_CONSTANT(bool, value = true); }; +template <> struct is_signed_helper<unsigned long long> { BOOST_STATIC_CONSTANT(bool, value = false); }; +template <> struct is_signed_helper<float> { BOOST_STATIC_CONSTANT(bool, value = true); }; +template <> struct is_signed_helper<double> { BOOST_STATIC_CONSTANT(bool, value = true); }; + +#endif + template <bool integral_type> struct is_signed_select_helper { Index: is_unsigned.hpp =================================================================== RCS file: /cvsroot/boost/boost/boost/type_traits/is_unsigned.hpp,v retrieving revision 1.1 diff -u -r1.1 is_unsigned.hpp --- is_unsigned.hpp 30 Jan 2005 15:47:45 -0000 1.1 +++ is_unsigned.hpp 2 Feb 2005 06:42:43 -0000 @@ -21,12 +21,35 @@ namespace detail{ +#if !(defined(__EDG_VERSION__) && __EDG_VERSION__ == 238) + template <class T> struct is_unsigned_helper { BOOST_STATIC_CONSTANT(bool, value = (static_cast<T>(-1) > 0)); }; +#else + +template <class T> +struct is_unsigned_helper; + +template <> struct is_unsigned_helper<char> { BOOST_STATIC_CONSTANT(bool, value = true); }; +template <> struct is_unsigned_helper<signed char> { BOOST_STATIC_CONSTANT(bool, value = false); }; +template <> struct is_unsigned_helper<unsigned char> { BOOST_STATIC_CONSTANT(bool, value = true); }; +template <> struct is_unsigned_helper<short> { BOOST_STATIC_CONSTANT(bool, value = false); }; +template <> struct is_unsigned_helper<unsigned short> { BOOST_STATIC_CONSTANT(bool, value = true); }; +template <> struct is_unsigned_helper<int> { BOOST_STATIC_CONSTANT(bool, value = false); }; +template <> struct is_unsigned_helper<unsigned int> { BOOST_STATIC_CONSTANT(bool, value = true); }; +template <> struct is_unsigned_helper<long> { BOOST_STATIC_CONSTANT(bool, value = false); }; +template <> struct is_unsigned_helper<unsigned long> { BOOST_STATIC_CONSTANT(bool, value = true); }; +template <> struct is_unsigned_helper<long long> { BOOST_STATIC_CONSTANT(bool, value = false); }; +template <> struct is_unsigned_helper<unsigned long long> { BOOST_STATIC_CONSTANT(bool, value = true); }; +template <> struct is_unsigned_helper<float> { BOOST_STATIC_CONSTANT(bool, value = false); }; +template <> struct is_unsigned_helper<double> { BOOST_STATIC_CONSTANT(bool, value = false); }; + +#endif + template <bool integral_type> struct is_unsigned_select_helper { __________________________________ Do you Yahoo!? Meet the all-new My Yahoo! - Try it today! http://my.yahoo.com

The recent changes to the type_traits library break our Boost.Python builds under IRIX, using the old MIPSpro 7.3.1 compiler. This compiler is based on EDG 238. The problem is illustrated by this simple piece of code:
template <class T> struct is_signed_helper { static const bool value = (static_cast<T>(-1) < 0); };
Just when I thought I had got away with that update! I take it changing the static_cast to a C style cast doesn't do the job? John.

--- John Maddock <john@johnmaddock.co.uk> wrote:
Just when I thought I had got away with that update!
I take it changing the static_cast to a C style cast doesn't do the job?
That's something I hadn't thought of. Unfortunately it doesn't help. See below. template <class T> struct is_signed_helper { static const bool value = ((T)(-1) < 0); }; % CC -n32 -mips4 -LANG:std -c foo.cpp cc-3314 CC: ERROR File = foo.cpp, Line = 4 The expression must have arithmetic, enum, or pointer type. static const bool value = ((T)(-1) < 0); ^ 1 error detected in the compilation of "foo.cpp". template <class T> struct is_signed_helper { static const T minus_one = static_cast<T>(-1); static const bool value = (minus_one < 0); }; % CC -n32 -mips4 -LANG:std -c foo.cpp cc-3314 CC: ERROR File = foo.cpp, Line = 5 The expression must have arithmetic, enum, or pointer type. static const bool value = (minus_one < 0); ^ 1 error detected in the compilation of "foo.cpp". template <class T> struct is_signed_helper { static const T minus_one = static_cast<T>(-1); static const bool value = (minus_one < 0 ? true : false); }; % CC -n32 -mips4 -LANG:std -c foo.cpp cc-3314 CC: ERROR File = foo.cpp, Line = 5 The expression must have arithmetic, enum, or pointer type. static const bool value = (minus_one < 0 ? true : false); ^ 1 error detected in the compilation of "foo.cpp". template <class T> struct is_signed_helper { static const T minus_one = static_cast<T>(-1); static const bool value = minus_one < 0 ? true : false; }; % CC -n32 -mips4 -LANG:std -c foo.cpp cc-3314 CC: ERROR File = foo.cpp, Line = 5 The expression must have arithmetic, enum, or pointer type. static const bool value = minus_one < 0 ? true : false; ^ 1 error detected in the compilation of "foo.cpp". template <class T> struct is_signed_helper { typedef T t_type; static const bool value = (static_cast<t_type>(-1) < 0); }; % CC -n32 -mips4 -LANG:std -c foo.cpp cc-3314 CC: ERROR File = foo.cpp, Line = 5 The expression must have arithmetic, enum, or pointer type. static const bool value = (static_cast<t_type>(-1) < 0); ^ 1 error detected in the compilation of "foo.cpp". template <class T> struct is_signed_helper { typedef T t_type; static const bool value = ((t_type)(-1) < 0); }; % CC -n32 -mips4 -LANG:std -c foo.cpp cc-3314 CC: ERROR File = foo.cpp, Line = 5 The expression must have arithmetic, enum, or pointer type. static const bool value = ((t_type)(-1) < 0); ^ 1 error detected in the compilation of "foo.cpp". // I am not sure about the validity of this one, but just // to show that the error persists: #include <functional> template <class T> struct is_signed_helper { static const bool value = std::less<T>()(static_cast<T>(-1), 0); }; % CC -n32 -mips4 -LANG:std -c foo.cpp cc-1028 CC: ERROR File = foo.cpp, Line = 6 The expression used must have a constant value. static const bool value = std::less<T>()(static_cast<T>(-1), 0); ^ cc-1059 CC: ERROR File = foo.cpp, Line = 6 A function call is not allowed in a constant expression. static const bool value = std::less<T>()(static_cast<T>(-1), 0); ^ 2 errors detected in the compilation of "foo.cpp". // This one works, but any attempt to convert -1 appears to be doomed to fail. template <class T> struct is_signed_helper { static const bool value = (-1u < 0); }; __________________________________ Do you Yahoo!? Read only the mail you want - Yahoo! Mail SpamGuard. http://promotions.yahoo.com/new_mail

--- John Maddock <john@johnmaddock.co.uk> wrote:
That's something I hadn't thought of. Unfortunately it doesn't help. See below.
Looks like you tested everything going there!
I'll go with your fix,
Thanks a lot for your support! I noticed that an exclamation mark is missing, most likeley: Index: is_signed.hpp =================================================================== RCS file: /cvsroot/boost/boost/boost/type_traits/is_signed.hpp,v retrieving revision 1.2 diff -r1.2 is_signed.hpp 24c24 < #if (defined(__EDG_VERSION__) && __EDG_VERSION__ <= 238) ---
#if !(defined(__EDG_VERSION__) && __EDG_VERSION__ <= 238)
I've inserted the exclamation mark locally and, also using Jonathan's bool patch, everything builds and runs correctly again (14 different environments). Cheers, Ralf __________________________________ Do you Yahoo!? The all-new My Yahoo! - Get yours free! http://my.yahoo.com

Thanks a lot for your support! I noticed that an exclamation mark is missing, most likeley:
I've inserted the exclamation mark locally and, also using Jonathan's bool patch, everything builds and runs correctly again (14 different environments).
Well spotted, thanks, will be in cvs shortly. John.
participants (2)
-
John Maddock
-
Ralf W. Grosse-Kunstleve