zorba-coders team mailing list archive
-
zorba-coders team
-
Mailing list archive
-
Message #08137
[Merge] lp:~paul-lucas/zorba/bug-951016 into lp:zorba
Paul J. Lucas has proposed merging lp:~paul-lucas/zorba/bug-951016 into lp:zorba.
Requested reviews:
Matthias Brantner (matthias-brantner)
Paul J. Lucas (paul-lucas)
Related bugs:
Bug #951016 in Zorba: "integer comparison warning in integer.h"
https://bugs.launchpad.net/zorba/+bug/951016
For more details, see:
https://code.launchpad.net/~paul-lucas/zorba/bug-951016/+merge/102540
Added new functions to do in-range checks without warnings.
--
https://code.launchpad.net/~paul-lucas/zorba/bug-951016/+merge/102540
Your team Zorba Coders is subscribed to branch lp:zorba.
=== modified file 'src/util/stl_util.h'
--- src/util/stl_util.h 2012-04-16 20:56:43 +0000
+++ src/util/stl_util.h 2012-04-18 15:29:21 +0000
@@ -292,6 +292,80 @@
///////////////////////////////////////////////////////////////////////////////
+//
+// These functions are used to test whether a value of numeric type N1 is
+// within the range of another numeric type N2. It correctly handles the
+// cases where the "signed-ness" of N1 and N2 differ such that the code is
+// warning-free.
+//
+
+template<typename N1,typename N2> inline
+typename std::enable_if<ZORBA_TR1_NS::is_signed<N1>::value
+ && ZORBA_TR1_NS::is_signed<N2>::value,bool>::type
+ge_min( N1 n1, N2 ) {
+ return n1 >= std::numeric_limits<N2>::min();
+}
+
+template<typename N1,typename N2> inline
+typename std::enable_if<ZORBA_TR1_NS::is_signed<N1>::value
+ && ZORBA_TR1_NS::is_unsigned<N2>::value,bool>::type
+ge_min( N1 n1, N2 ) {
+ return n1 >= 0;
+}
+
+template<typename N1,typename N2> inline
+typename std::enable_if<ZORBA_TR1_NS::is_unsigned<N1>::value
+ && ZORBA_TR1_NS::is_signed<N2>::value,bool>::type
+ge_min( N1, N2 ) {
+ return true;
+}
+
+template<typename N1,typename N2> inline
+typename std::enable_if<ZORBA_TR1_NS::is_unsigned<N1>::value
+ && ZORBA_TR1_NS::is_unsigned<N2>::value,bool>::type
+ge_min( N1, N2 ) {
+ return true;
+}
+
+template<typename N1,typename N2> inline
+typename std::enable_if<ZORBA_TR1_NS::is_signed<N1>::value
+ && ZORBA_TR1_NS::is_signed<N2>::value,bool>::type
+le_max( N1 n1, N2 ) {
+ return n1 <= std::numeric_limits<N2>::max();
+}
+
+template<typename N1,typename N2> inline
+typename std::enable_if<ZORBA_TR1_NS::is_signed<N1>::value
+ && ZORBA_TR1_NS::is_unsigned<N2>::value,bool>::type
+le_max( N1 n1, N2 ) {
+ return n1 <= 0 || static_cast<N2>( n1 ) <= std::numeric_limits<N2>::max();
+}
+
+template<typename N1,typename N2> inline
+typename std::enable_if<ZORBA_TR1_NS::is_unsigned<N1>::value
+ && ZORBA_TR1_NS::is_signed<N2>::value,bool>::type
+le_max( N1 n1, N2 ) {
+ return n1 <= static_cast<N1>( std::numeric_limits<N2>::max() );
+}
+
+template<typename N1,typename N2> inline
+typename std::enable_if<ZORBA_TR1_NS::is_unsigned<N1>::value
+ && ZORBA_TR1_NS::is_unsigned<N2>::value,bool>::type
+le_max( N1 n1, N2 ) {
+ return n1 <= std::numeric_limits<N2>::max();
+}
+
+#define ZORBA_GE_MIN(N,T) \
+ ::zorba::ztd::ge_min( N, static_cast<T>(0) )
+
+#define ZORBA_LE_MAX(N,T) \
+ ::zorba::ztd::le_max( N, static_cast<T>(0) )
+
+#define ZORBA_IN_RANGE(N,T) \
+ ( ZORBA_GE_MIN(N,T) && ZORBA_LE_MAX(N,T) )
+
+///////////////////////////////////////////////////////////////////////////////
+
template<typename T> class stack_generator {
std::stack<T> &stk;
public:
=== modified file 'src/zorbatypes/decimal.h'
--- src/zorbatypes/decimal.h 2012-04-17 16:07:10 +0000
+++ src/zorbatypes/decimal.h 2012-04-18 15:29:21 +0000
@@ -200,7 +200,9 @@
////////// miscellaneous ////////////////////////////////////////////////////
- bool is_integer() const;
+ bool is_xs_int() const;
+ bool is_xs_integer() const;
+ bool is_xs_long() const;
uint32_t hash() const;
@@ -227,8 +229,6 @@
static uint32_t hash( value_type const& );
- bool is_xs_long() const;
-
enum parse_options {
parse_integer,
parse_decimal
@@ -387,13 +387,18 @@
return hash( value_ );
}
-inline bool Decimal::is_integer() const {
+inline bool Decimal::is_xs_int() const {
+ return value_.is_integer() &&
+ value_ >= MAPM::getMinInt32() && value_ <= MAPM::getMaxInt32();
+}
+
+inline bool Decimal::is_xs_integer() const {
return value_.is_integer() != 0;
}
inline bool Decimal::is_xs_long() const {
return value_.is_integer() &&
- value_ > MAPM::getMinInt64() && value_ < MAPM::getMaxInt64();
+ value_ >= MAPM::getMinInt64() && value_ <= MAPM::getMaxInt64();
}
inline int Decimal::sign() const {
=== modified file 'src/zorbatypes/integer.cpp'
--- src/zorbatypes/integer.cpp 2012-04-17 16:07:10 +0000
+++ src/zorbatypes/integer.cpp 2012-04-18 15:29:21 +0000
@@ -259,7 +259,7 @@
TEMPLATE_DECL(T)
bool operator==( INTEGER_IMPL(T) const &i, Decimal const &d ) {
- return d.is_integer() && i.itod() == d.value_;
+ return d.is_xs_integer() && i.itod() == d.value_;
}
#define ZORBA_INTEGER_OP(OP) \
@@ -366,7 +366,7 @@
TEMPLATE_DECL(T)
MAPM INTEGER_IMPL(T)::itod() const {
- if ( is_long() )
+ if ( is_cxx_long() )
return static_cast<long>( value_ );
ztd::itoa_buf_type buf;
return ztd::itoa( value_, buf );
@@ -377,6 +377,38 @@
uint32_t IntegerImpl::hash() const {
return Decimal::hash( value_ );
}
+
+bool IntegerImpl::is_xs_byte() const {
+ static MAPM xs_byte_min( "-128" );
+ static MAPM xs_byte_max( "127" );
+ return value_ >= xs_byte_min && value_ <= xs_byte_max;
+}
+
+bool IntegerImpl::is_xs_short() const {
+ static MAPM xs_short_min( "-32768" );
+ static MAPM xs_short_max( "32767" );
+ return value_ >= xs_short_min && value_ <= xs_short_max;
+}
+
+bool IntegerImpl::is_xs_unsignedByte() const {
+ static MAPM xs_unsignedByte_max( "256" );
+ return value_.sign() >= 0 && value_ <= xs_unsignedByte_max;
+}
+
+bool IntegerImpl::is_xs_unsignedInt() const {
+ static MAPM xs_unsignedInt_max( "4294967295" );
+ return value_.sign() >= 0 && value_ <= xs_unsignedInt_max;
+}
+
+bool IntegerImpl::is_xs_unsignedLong() const {
+ static MAPM xs_unsignedLong_max( "18446744073709551615" );
+ return value_.sign() >= 0 && value_ <= xs_unsignedLong_max;
+}
+
+bool IntegerImpl::is_xs_unsignedShort() const {
+ static MAPM xs_unsignedShort_max( "65536" );
+ return value_.sign() >= 0 && value_ <= xs_unsignedShort_max;
+}
#endif /* ZORBA_WITH_BIG_INTEGER */
TEMPLATE_DECL(T)
=== modified file 'src/zorbatypes/integer.h'
--- src/zorbatypes/integer.h 2012-04-17 16:07:10 +0000
+++ src/zorbatypes/integer.h 2012-04-18 15:29:21 +0000
@@ -439,6 +439,15 @@
int compare( IntegerImpl const& ) const;
uint32_t hash() const;
+ bool is_cxx_long() const;
+ bool is_xs_byte() const;
+ bool is_xs_int() const;
+ bool is_xs_long() const;
+ bool is_xs_short() const;
+ bool is_xs_unsignedByte() const;
+ bool is_xs_unsignedInt() const;
+ bool is_xs_unsignedLong() const;
+ bool is_xs_unsignedShort() const;
int sign() const;
zstring toString() const;
static IntegerImpl const& one();
@@ -478,8 +487,8 @@
static value_type make_value_type( T n ) {
return value_type( static_cast<int_cast_type>( n ) );
}
+
#else /* ZORBA_WITH_BIG_INTEGER */
- bool is_long() const;
static value_type ftoi( value_type v ) {
return v; // intentional no-op
@@ -1028,6 +1037,14 @@
return value_.compare( i.value_ );
}
+inline bool Decimal::is_xs_int() const {
+ return value_ >= MAPM::getMinInt32() && value_ <= MAPM::getMaxInt32();
+}
+
+inline bool IntegerImpl::is_xs_long() const {
+ return value_ >= MAPM::getMinInt64() && value_ <= MAPM::getMaxInt64();
+}
+
inline int IntegerImpl::sign() const {
return value_.sign();
}
@@ -1045,9 +1062,48 @@
}
template<typename I>
-inline bool IntegerImpl<I>::is_long() const {
- return value_ >= std::numeric_limits<long>::min() &&
- value_ <= std::numeric_limits<long>::max();
+inline bool IntegerImpl<I>::is_cxx_long() const {
+ return ZORBA_IN_RANGE( value_, long );
+}
+
+template<typename I>
+inline bool IntegerImpl<I>::is_xs_byte() const {
+ return ZORBA_IN_RANGE( value_, xs_byte );
+}
+
+template<typename I>
+inline bool IntegerImpl<I>::is_xs_int() const {
+ return ZORBA_IN_RANGE( value_, xs_int );
+}
+
+template<typename I>
+inline bool IntegerImpl<I>::is_xs_long() const {
+ return ZORBA_IN_RANGE( value_, xs_long );
+}
+
+template<typename I>
+inline bool IntegerImpl<I>::is_xs_short() const {
+ return ZORBA_IN_RANGE( value_, xs_short );
+}
+
+template<typename I>
+inline bool IntegerImpl<I>::is_xs_unsignedByte() const {
+ return ZORBA_IN_RANGE( value_, xs_unsignedByte );
+}
+
+template<typename I>
+inline bool IntegerImpl<I>::is_xs_unsignedInt() const {
+ return ZORBA_IN_RANGE( value_, xs_unsignedInt );
+}
+
+template<typename I>
+inline bool IntegerImpl<I>::is_xs_unsignedLong() const {
+ return ZORBA_IN_RANGE( value_, xs_unsignedLong );
+}
+
+template<typename I>
+inline bool IntegerImpl<I>::is_xs_unsignedShort() const {
+ return ZORBA_IN_RANGE( value_, xs_unsignedShort );
}
template<typename I>
Follow ups