sl@0: // sl@0: // boost limits_test.cpp test your file for important sl@0: // Copyright Jens Maurer 2000 sl@0: // Permission to use, copy, modify, sell, and distribute this software sl@0: // is hereby granted without fee provided that the above copyright notice sl@0: // appears in all copies and that both that copyright notice and this sl@0: // permission notice appear in supporting documentation, sl@0: // Jens Maurer makes no representations about the suitability of this sl@0: // software for any purpose. It is provided "as is" without express or sl@0: // implied warranty. sl@0: // sl@0: // sl@0: sl@0: #include sl@0: sl@0: #include "cppunit/cppunit_proxy.h" sl@0: sl@0: #if !defined (STLPORT) || defined(_STLP_USE_NAMESPACES) sl@0: using namespace std; sl@0: #endif sl@0: sl@0: // sl@0: // TestCase class sl@0: // sl@0: class LimitTest : public CPPUNIT_NS::TestCase sl@0: { sl@0: CPPUNIT_TEST_SUITE(LimitTest); sl@0: CPPUNIT_TEST(test); sl@0: # if defined (__BORLANDC__) sl@0: CPPUNIT_IGNORE; sl@0: # endif sl@0: CPPUNIT_TEST(qnan_test); sl@0: CPPUNIT_TEST(limits_cov); sl@0: CPPUNIT_TEST_SUITE_END(); sl@0: sl@0: protected: sl@0: void test(); sl@0: void qnan_test(); sl@0: void limits_cov(); sl@0: }; sl@0: sl@0: CPPUNIT_TEST_SUITE_REGISTRATION(LimitTest); sl@0: sl@0: # define CHECK_COND(X) if (!(X)) return false; sl@0: sl@0: bool valid_sign_info(bool, bool) sl@0: { return true; } sl@0: sl@0: template sl@0: bool valid_sign_info(bool limit_is_signed, const _Tp &) { sl@0: return limit_is_signed && _Tp(-1) < 0 || sl@0: !limit_is_signed && _Tp(-1) > 0; sl@0: } sl@0: sl@0: template sl@0: bool test_integral_limits(const _Tp &, bool unknown_sign = true, bool is_signed = true) { sl@0: typedef numeric_limits<_Tp> lim; sl@0: sl@0: CHECK_COND(lim::is_specialized); sl@0: CHECK_COND(lim::is_integer); sl@0: /*CHECK_COND(lim::is_modulo);*/ sl@0: CHECK_COND(lim::min() < lim::max()); sl@0: CHECK_COND((unknown_sign && ((lim::is_signed && (lim::min() != 0)) || (!lim::is_signed && (lim::min() == 0)))) || sl@0: (!unknown_sign && ((lim::is_signed && is_signed) || (!lim::is_signed && !is_signed)))); sl@0: sl@0: if (unknown_sign) { sl@0: CHECK_COND(valid_sign_info(lim::is_signed, _Tp())); sl@0: } sl@0: return true; sl@0: } sl@0: sl@0: template sl@0: bool test_signed_integral_limits(const _Tp &__val) { sl@0: return test_integral_limits(__val, false, true); sl@0: } sl@0: template sl@0: bool test_unsigned_integral_limits(const _Tp &__val) { sl@0: return test_integral_limits(__val, false, false); sl@0: } sl@0: sl@0: template sl@0: bool test_float_limits(const _Tp &) { sl@0: typedef numeric_limits<_Tp> lim; sl@0: CHECK_COND(lim::is_specialized); sl@0: CHECK_COND(!lim::is_modulo); sl@0: CHECK_COND(!lim::is_integer); sl@0: CHECK_COND(lim::is_signed); sl@0: sl@0: CHECK_COND(lim::max() > 1000); sl@0: CHECK_COND(lim::min() > 0); sl@0: CHECK_COND(lim::min() < 0.001); sl@0: CHECK_COND(lim::epsilon() > 0); sl@0: sl@0: if (lim::is_iec559) { sl@0: CHECK_COND(lim::has_infinity); sl@0: CHECK_COND(lim::has_quiet_NaN); sl@0: CHECK_COND(lim::has_signaling_NaN); sl@0: CHECK_COND(lim::signaling_NaN); sl@0: } sl@0: sl@0: if (lim::has_infinity) { sl@0: const _Tp infinity = lim::infinity(); sl@0: /* Make sure those values are not 0 or similar nonsense. sl@0: * Infinity must compare as if larger than the maximum representable value. sl@0: */ sl@0: CHECK_COND(infinity > lim::max()); sl@0: CHECK_COND(-infinity < -lim::max()); sl@0: } sl@0: return true; sl@0: } sl@0: sl@0: template sl@0: bool test_qnan(const _Tp &) { sl@0: typedef numeric_limits<_Tp> lim; sl@0: if (lim::has_quiet_NaN) { sl@0: const _Tp qnan = lim::quiet_NaN(); sl@0: sl@0: /* NaNs shall always compare "false" when compared for equality sl@0: * If one of these fail, your compiler may be optimizing incorrectly, sl@0: * or the STLport is incorrectly configured. sl@0: */ sl@0: CHECK_COND(! (qnan == 42)); sl@0: CHECK_COND(! (qnan == qnan)); sl@0: CHECK_COND(qnan != 42); sl@0: CHECK_COND(qnan != qnan); sl@0: sl@0: /* The following tests may cause arithmetic traps. sl@0: * CHECK_COND(! (qnan < 42)); sl@0: * CHECK_COND(! (qnan > 42)); sl@0: * CHECK_COND(! (qnan <= 42)); sl@0: * CHECK_COND(! (qnan >= 42)); sl@0: */ sl@0: } sl@0: return true; sl@0: } sl@0: void LimitTest::test() { sl@0: CPPUNIT_ASSERT(test_integral_limits(bool())); sl@0: /* sl@0: It is implementation-defined whether a char object can hold sl@0: negative values. Characters can be explicitly declared unsigned or signed. Plain char, signed char, and unsigned sl@0: char are three distinct types. sl@0: */ sl@0: //CPPUNIT_ASSERT(test_integral_limits(char())); sl@0: typedef signed char signed_char; sl@0: CPPUNIT_ASSERT(test_signed_integral_limits(signed_char())); sl@0: typedef unsigned char unsigned_char; sl@0: CPPUNIT_ASSERT(test_unsigned_integral_limits(unsigned_char())); sl@0: # if defined (_STLP_HAS_WCHAR_T) && !defined (_STLP_WCHAR_T_IS_USHORT) sl@0: CPPUNIT_ASSERT(test_integral_limits(wchar_t())); sl@0: # endif sl@0: CPPUNIT_ASSERT(test_signed_integral_limits(short())); sl@0: typedef unsigned short unsigned_short; sl@0: CPPUNIT_ASSERT(test_unsigned_integral_limits(unsigned_short())); sl@0: CPPUNIT_ASSERT(test_signed_integral_limits(int())); sl@0: typedef unsigned int unsigned_int; sl@0: CPPUNIT_ASSERT(test_unsigned_integral_limits(unsigned_int())); sl@0: CPPUNIT_ASSERT(test_signed_integral_limits(long())); sl@0: typedef unsigned long unsigned_long; sl@0: CPPUNIT_ASSERT(test_unsigned_integral_limits(unsigned_long())); sl@0: # if defined (_STLP_LONG_LONG) sl@0: typedef _STLP_LONG_LONG long_long; sl@0: CPPUNIT_ASSERT(test_signed_integral_limits(long_long())); sl@0: typedef unsigned _STLP_LONG_LONG unsigned_long_long; sl@0: CPPUNIT_ASSERT(test_unsigned_integral_limits(unsigned_long_long())); sl@0: #endif sl@0: sl@0: CPPUNIT_ASSERT(test_float_limits(float())); sl@0: CPPUNIT_ASSERT(test_float_limits(double())); sl@0: # if !defined ( _STLP_NO_LONG_DOUBLE ) sl@0: typedef long double long_double; sl@0: CPPUNIT_ASSERT(test_float_limits(long_double())); sl@0: # endif sl@0: } sl@0: sl@0: void LimitTest::qnan_test() { sl@0: CPPUNIT_ASSERT(test_qnan(float())); sl@0: CPPUNIT_ASSERT(test_qnan(double())); sl@0: # if !defined ( _STLP_NO_LONG_DOUBLE ) sl@0: typedef long double long_double; sl@0: CPPUNIT_ASSERT(test_qnan(long_double())); sl@0: # endif sl@0: } sl@0: void LimitTest::limits_cov() sl@0: { sl@0: if(numeric_limits::has_denorm == false) sl@0: { sl@0: CPPUNIT_ASSERT(numeric_limits::denorm_min( )); // denorm_min for float sl@0: CPPUNIT_ASSERT(numeric_limits::denorm_min( )); // denorm_min for double sl@0: CPPUNIT_ASSERT(numeric_limits::denorm_min( )); // denorm_min for long double sl@0: } sl@0: numeric_limits::round_error( ); // round_error for float sl@0: numeric_limits::round_error( ); // round_error for double sl@0: numeric_limits::round_error( ); // round_error for long double sl@0: if(numeric_limits::is_iec559) sl@0: { sl@0: CPPUNIT_ASSERT(numeric_limits::infinity( )); // infinity for long double sl@0: CPPUNIT_ASSERT(numeric_limits::quiet_NaN( ));// quiet_NaN for long double sl@0: } sl@0: }