# HG changeset patch # User John W. Eaton # Date 1203839881 18000 # Node ID 6f10bbb2854afddb9f2660d8146fde76b83f184f # Parent b166043585a87263340b2ce69b5c159d9791aac8 avoid some GCC warnings for unsigned comparisons diff --git a/liboctave/ChangeLog b/liboctave/ChangeLog --- a/liboctave/ChangeLog +++ b/liboctave/ChangeLog @@ -1,3 +1,15 @@ +2008-02-24 John W. Eaton + + * oct-inttypes.h (octave_int_helper): New class. Provide + specializations for signed and unsigned types. + (octave_int::operator >>=, octave_int::abs, + octave_int::signum): Use static functions from + octave_int_helper class. + + * oct-inttypes.h, oct-inttypes.cc (OCTAVE_US_TYPE1_CMP_OP, + OCTAVE_US_TYPE2_CMP_OP): Tag function declarations and definitions + with "template <>". + 2008-02-22 John W. Eaton * CSparse.cc, SparseCmplxLU.cc, SparsedbleLU.cc, dSparse.cc, diff --git a/liboctave/oct-inttypes.cc b/liboctave/oct-inttypes.cc --- a/liboctave/oct-inttypes.cc +++ b/liboctave/oct-inttypes.cc @@ -286,6 +286,7 @@ // type and compare). #define OCTAVE_US_TYPE1_CMP_OP(OP, LTZ_VAL, UT, ST) \ + template <> \ bool \ operator OP (const octave_int& lhs, const octave_int& rhs) \ { \ @@ -302,6 +303,7 @@ OCTAVE_US_TYPE1_CMP_OP (!=, true, UT, ST) #define OCTAVE_SU_TYPE1_CMP_OP(OP, LTZ_VAL, ST, UT) \ + template <> \ bool \ operator OP (const octave_int& lhs, const octave_int& rhs) \ { \ @@ -335,6 +337,7 @@ // compare if the signed value is positive). #define OCTAVE_US_TYPE2_CMP_OP(OP, LTZ_VAL, UT, ST) \ + template <> \ bool \ operator OP (const octave_int& lhs, const octave_int& rhs) \ { \ @@ -351,6 +354,7 @@ OCTAVE_US_TYPE2_CMP_OP (!=, true, ST, UT) #define OCTAVE_SU_TYPE2_CMP_OP(OP, LTZ_VAL, ST, UT) \ + template <> \ bool \ operator OP (const octave_int& lhs, const octave_int& rhs) \ { \ diff --git a/liboctave/oct-inttypes.h b/liboctave/oct-inttypes.h --- a/liboctave/oct-inttypes.h +++ b/liboctave/oct-inttypes.h @@ -199,6 +199,61 @@ OCTAVE_INT_MIN_VAL2 (T1, T2), \ OCTAVE_INT_MAX_VAL2 (T1, T2)) +// By using these classes/functions we avoid warnings from GCC about +// comparisons always being false due to limited range of data type. + +// FIXME -- it would be nice to nest the helper class inside the +// octave_int class, but I don't see the magic for that at the moment. + +template class octave_int; + +template +class octave_int_helper +{ +public: + static octave_int abs (const T& x); + + static octave_int signum (const T& x); + + template static void rshift_eq (T& ival, const T2& x); +}; + +template +class octave_int_helper +{ +public: + static octave_int + abs (const T& x) { return x; } + + static octave_int + signum (const T& x) { return x > 0 ? 1 : 0; } + + template + static void + rshift_eq (T& ival, const T2& x) { ival = ival >> x; } +}; + +template +class octave_int_helper +{ +public: + static octave_int + abs (const T& x) { return x < 0 ? -x : x; } + + static octave_int + signum (const T& x) { return x < 0 ? -1 : (x > 0 ? 1 : 0); } + + template + static void + rshift_eq (T& ival, const T2& x) + { + if (ival < 0) + ival = - (((-ival) >> x) & std::numeric_limits::max()); + else + ival = ival >> x; + } +}; + template class octave_int @@ -306,32 +361,26 @@ return *this; } + // Use helper functions in the operator >>=, abs, and signum + // functions to avoid "comparison of unsigned expression < 0 is + // always false" warnings from GCC when instantiating these funtions + // for unsigned types. + template octave_int& operator >>= (const T2& x) { - if (ival < 0) - ival = - (((-ival) >> x) & std::numeric_limits::max()); - else - ival = ival >> x; + octave_int_helper::is_signed>::rshift_eq (ival, x); return *this; } - octave_int abs (void) const - { - T val = value (); - if (val < static_cast (0)) - val = - val; - return val; + octave_int abs (void) const + { + return octave_int_helper::is_signed>::abs (value ()); } octave_int signum (void) const { - T val = value (); - if (val < static_cast (0)) - val = - static_cast (1); - else if (val > static_cast (0)) - val = static_cast (1); - return val; + return octave_int_helper::is_signed>::signum (value ()); } octave_int min (void) const { return std::numeric_limits::min (); } @@ -585,7 +634,9 @@ // type and compare). #define OCTAVE_US_TYPE1_CMP_OP_DECL(OP, LTZ_VAL, UT, ST) \ - bool OCTAVE_API operator OP (const octave_int& lhs, const octave_int& rhs); + template <> \ + bool \ + OCTAVE_API operator OP (const octave_int& lhs, const octave_int& rhs); #define OCTAVE_US_TYPE1_CMP_OP_DECLS(UT, ST) \ OCTAVE_US_TYPE1_CMP_OP_DECL (<, false, UT, ST) \ @@ -596,7 +647,9 @@ OCTAVE_US_TYPE1_CMP_OP_DECL (!=, true, UT, ST) #define OCTAVE_SU_TYPE1_CMP_OP_DECL(OP, LTZ_VAL, ST, UT) \ - bool OCTAVE_API operator OP (const octave_int& lhs, const octave_int& rhs); + template <> \ + bool \ + OCTAVE_API operator OP (const octave_int& lhs, const octave_int& rhs); #define OCTAVE_SU_TYPE1_CMP_OP_DECLS(ST, UT) \ OCTAVE_SU_TYPE1_CMP_OP_DECL (<, true, ST, UT) \ @@ -624,7 +677,9 @@ // compare if the signed value is positive). #define OCTAVE_US_TYPE2_CMP_OP_DECL(OP, LTZ_VAL, UT, ST) \ - bool OCTAVE_API operator OP (const octave_int& lhs, const octave_int& rhs); + template <> \ + bool \ + OCTAVE_API operator OP (const octave_int& lhs, const octave_int& rhs); #define OCTAVE_US_TYPE2_CMP_OP_DECLS(ST, UT) \ OCTAVE_US_TYPE2_CMP_OP_DECL (<, false, ST, UT) \ @@ -635,7 +690,9 @@ OCTAVE_US_TYPE2_CMP_OP_DECL (!=, true, ST, UT) #define OCTAVE_SU_TYPE2_CMP_OP_DECL(OP, LTZ_VAL, ST, UT) \ - bool OCTAVE_API operator OP (const octave_int& lhs, const octave_int& rhs); + template <> \ + bool \ + OCTAVE_API operator OP (const octave_int& lhs, const octave_int& rhs); #define OCTAVE_SU_TYPE2_CMP_OP_DECLS(ST, UT) \ OCTAVE_SU_TYPE2_CMP_OP_DECL (<, true, ST, UT) \