ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

limits_test.cpp
Go to the documentation of this file.
00001 /* boost limits_test.cpp   test your <limits> file for important
00002  *
00003  * Copyright Jens Maurer 2000
00004  * Permission to use, copy, modify, sell, and distribute this software
00005  * is hereby granted without fee provided that the above copyright notice
00006  * appears in all copies and that both that copyright notice and this
00007  * permission notice appear in supporting documentation,
00008  *
00009  * Jens Maurer makes no representations about the suitability of this
00010  * software for any purpose. It is provided "as is" without express or
00011  * implied warranty.
00012  *
00013  */
00014 
00015 #include <limits>
00016 //#include <sstream>
00017 
00018 #include "cppunit/cppunit_proxy.h"
00019 
00020 #if !defined (STLPORT) || defined(_STLP_USE_NAMESPACES)
00021 using namespace std;
00022 #endif
00023 
00024 //
00025 // TestCase class
00026 //
00027 class LimitTest : public CPPUNIT_NS::TestCase
00028 {
00029   CPPUNIT_TEST_SUITE(LimitTest);
00030 #  if defined (__BORLANDC__)
00031   /* Ignore FPU exceptions, set FPU precision to 64 bits */
00032   unsigned int _float_control_word = _control87(0, 0);
00033   _control87(PC_64|MCW_EM|IC_AFFINE, MCW_PC|MCW_EM|MCW_IC);
00034 #  endif
00035   CPPUNIT_TEST(test);
00036   CPPUNIT_TEST(qnan_test);
00037 #  if defined (__BORLANDC__)
00038   /* Reset floating point control word */
00039   _clear87();
00040   _control87(_float_control_word, MCW_PC|MCW_EM|MCW_IC);
00041 #  endif
00042   CPPUNIT_TEST_SUITE_END();
00043 
00044 protected:
00045   void test();
00046   void qnan_test();
00047 };
00048 
00049 CPPUNIT_TEST_SUITE_REGISTRATION(LimitTest);
00050 
00051 #if defined (STLPORT) && defined (_STLP_STATIC_CONST_INIT_BUG)
00052 #  define CHECK_COND(X) if (!(X))  { CPPUNIT_MESSAGE(#X); return false; }
00053 #else
00054 //This version force to have external linkage on static constant which might
00055 //reveal that _STLP_NO_STATIC_CONST_DEFINITION should be commented.
00056 bool check_cond(const bool& cond) { return cond; }
00057 #  define CHECK_COND(X) if (!check_cond(X)) { CPPUNIT_MESSAGE(#X); return false; }
00058 #endif
00059 
00060 bool valid_sign_info(bool, bool)
00061 { return true; }
00062 
00063 template <class _Tp>
00064 bool valid_sign_info(bool limit_is_signed, const _Tp &) {
00065   return (limit_is_signed && _Tp(-1) < 0) ||
00066          (!limit_is_signed && _Tp(-1) > 0);
00067 }
00068 
00069 template <class _Tp>
00070 bool test_integral_limits_base(const _Tp &, bool unknown_sign = true, bool is_signed = true) {
00071   typedef numeric_limits<_Tp> lim;
00072 
00073   CHECK_COND(lim::is_specialized);
00074   CHECK_COND(lim::is_exact);
00075   CHECK_COND(lim::is_integer);
00076   CHECK_COND(!lim::is_iec559);
00077   CHECK_COND(lim::min() < lim::max());
00078   CHECK_COND((unknown_sign && ((lim::is_signed && (lim::min() != 0)) || (!lim::is_signed && (lim::min() == 0)))) ||
00079              (!unknown_sign && ((lim::is_signed && is_signed) || (!lim::is_signed && !is_signed))));
00080 
00081   if (unknown_sign) {
00082     CHECK_COND(valid_sign_info(lim::is_signed, _Tp()));
00083   }
00084   return true;
00085 }
00086 
00087 template <class _Tp>
00088 bool test_integral_limits(const _Tp &val, bool unknown_sign = true, bool is_signed = true) {
00089   if (!test_integral_limits_base(val, unknown_sign, is_signed))
00090     return false;
00091 
00092   typedef numeric_limits<_Tp> lim;
00093 
00094   CHECK_COND(lim::is_modulo);
00095 
00096   if (lim::is_bounded ||
00097      (!lim::is_bounded && !lim::is_signed)) {
00098     _Tp tmp = lim::min();
00099     CHECK_COND( --tmp > lim::min() );
00100   }
00101 
00102   if (lim::is_bounded) {
00103     _Tp tmp = lim::max();
00104     CHECK_COND( ++tmp < lim::max() );
00105   }
00106 
00107   return true;
00108 }
00109 
00110 template <class _Tp>
00111 bool test_signed_integral_limits(const _Tp &__val) {
00112   return test_integral_limits(__val, false, true);
00113 }
00114 template <class _Tp>
00115 bool test_unsigned_integral_limits(const _Tp &__val) {
00116   return test_integral_limits(__val, false, false);
00117 }
00118 
00119 template <class _Tp>
00120 bool test_float_values(_Tp lhs, _Tp rhs)
00121 { return lhs == rhs; }
00122 
00123 template <class _Tp>
00124 bool test_float_limits(const _Tp &) {
00125   typedef numeric_limits<_Tp> lim;
00126   CHECK_COND(lim::is_specialized);
00127   CHECK_COND(!lim::is_modulo);
00128   CHECK_COND(!lim::is_integer);
00129   CHECK_COND(lim::is_signed);
00130 
00131   CHECK_COND(lim::max() > 1000);
00132   CHECK_COND(lim::min() > 0);
00133   CHECK_COND(lim::min() < 0.001);
00134   CHECK_COND(lim::epsilon() > 0);
00135 
00136   if (lim::is_iec559) {
00137     CHECK_COND(lim::has_infinity);
00138     CHECK_COND(lim::has_quiet_NaN);
00139     CHECK_COND(lim::has_signaling_NaN);
00140     CHECK_COND(lim::has_denorm == denorm_present);
00141   }
00142 
00143   if (lim::has_denorm == denorm_absent) {
00144     CHECK_COND(lim::denorm_min() == lim::min());
00145     _Tp tmp = lim::min();
00146     tmp /= 2;
00147     if (tmp > 0 && tmp < lim::min()) {
00148       // has_denorm could be denorm_present
00149       CPPUNIT_MESSAGE("It looks like your compiler/platform supports denormalized floating point representation.");
00150     }
00151   }
00152   else if (lim::has_denorm == denorm_present) {
00153     CHECK_COND(lim::denorm_min() > 0);
00154     CHECK_COND(lim::denorm_min() < lim::min());
00155 
00156     _Tp tmp = lim::min();
00157     while (tmp != 0) {
00158       _Tp old_tmp = tmp;
00159       tmp /= 2;
00160       CHECK_COND(tmp < old_tmp);
00161       CHECK_COND(tmp >= lim::denorm_min() || tmp == (_Tp)0);
00162       //ostringstream str;
00163       //str << "denorm_min = " << lim::denorm_min() << ", tmp = " << tmp;
00164       //CPPUNIT_MESSAGE(str.str().c_str());
00165     }
00166   }
00167 
00168   if (lim::has_infinity) {
00169     const _Tp infinity = lim::infinity();
00170     /* Make sure those values are not 0 or similar nonsense.
00171      * Infinity must compare as if larger than the maximum representable value. */
00172 
00173     _Tp val = lim::max();
00174     val *= 2;
00175 
00176     /* We use test_float_values because without it some compilers (gcc) perform weird
00177      * optimization on the test giving unexpected result. */
00178     CHECK_COND(test_float_values(val, infinity));
00179 
00180     /*
00181     ostringstream str;
00182     str << "lim::max() = " << lim::max() << ", val = " << val << ", infinity = " << infinity;
00183     CPPUNIT_MESSAGE( str.str().c_str() );
00184     str.str(string());
00185     str << "sizeof(_Tp) = " << sizeof(_Tp);
00186     CPPUNIT_MESSAGE( str.str().c_str() );
00187     if (sizeof(_Tp) == 4) {
00188       str.str(string());
00189       str << "val in hexa: " << showbase << hex << *((const unsigned int*)&val);
00190       str << ", infinity in hexa: " << showbase << hex << *((const unsigned int*)&infinity);
00191     }
00192 #if defined (_STLP_LONG_LONG)
00193     else if (sizeof(_Tp) == sizeof(_STLP_LONG_LONG)) {
00194       str.str(string());
00195       str << "val in hexa: " << showbase << hex << *((const unsigned _STLP_LONG_LONG*)&val);
00196       str << ", infinity in hexa: " << showbase << hex << *((const unsigned _STLP_LONG_LONG*)&infinity);
00197     }
00198 #endif
00199     else {
00200       str.str(string());
00201       str << "val: ";
00202       for (int i = 0; i != sizeof(_Tp) /  sizeof(unsigned short); ++i) {
00203         if (i != 0) str << ' ';
00204         str << showbase << hex << setw(4) << setfill('0') << *((const unsigned short*)&val + i);
00205       }
00206       str << ", infinity: ";
00207       for (int i = 0; i != sizeof(_Tp) /  sizeof(unsigned short); ++i) {
00208         if (i != 0) str << ' ';
00209         str << showbase << hex << setw(4) << setfill('0') << *((const unsigned short*)&infinity + i);
00210       }
00211     }
00212     CPPUNIT_MESSAGE( str.str().c_str() );
00213     str.str(string());
00214     str << dec;
00215     str << "lim::digits = " << lim::digits << ", lim::digits10 = " << lim::digits10 << endl;
00216     str << "lim::min_exponent = " << lim::min_exponent << ", lim::min_exponent10 = " << lim::min_exponent10 << endl;
00217     str << "lim::max_exponent = " << lim::max_exponent << ", lim::max_exponent10 = " << lim::max_exponent10 << endl;
00218     CPPUNIT_MESSAGE( str.str().c_str() );
00219     */
00220 
00221     CHECK_COND(infinity == infinity);
00222     CHECK_COND(infinity > lim::max());
00223     CHECK_COND(-infinity < -lim::max());
00224   }
00225 
00226   return true;
00227 }
00228 
00229 //float generate_nan(float f) {
00230 //  return 0.0f / f;
00231 //}
00232 template <class _Tp>
00233 bool test_qnan(const _Tp &) {
00234   typedef numeric_limits<_Tp> lim;
00235   if (lim::has_quiet_NaN) {
00236     const _Tp qnan = lim::quiet_NaN();
00237 
00238     //if (sizeof(_Tp) == 4) {
00239     //  ostringstream str;
00240     //  str << "qnan " << qnan << ", in hexa: " << showbase << hex << *((unsigned int*)&qnan);
00241     //  CPPUNIT_MESSAGE( str.str().c_str() );
00242     //  str.str("");
00243     //  float val = generate_nan(0.0f);
00244     //  str << "val " << val << ", in hexa: " << showbase << hex << *((unsigned int*)&val);
00245     //  CPPUNIT_MESSAGE( str.str().c_str() );
00246     //  str.str("");
00247     //  val = -qnan;
00248     //  str << "-qnan " << val << ", in hexa: " << showbase << hex << *((unsigned int*)&val);
00249     //  CPPUNIT_MESSAGE( str.str().c_str() );
00250     //}
00251     /* NaNs shall always compare "false" when compared for equality
00252     * If one of these fail, your compiler may be optimizing incorrectly,
00253     * or the STLport is incorrectly configured.
00254     */
00255     CHECK_COND(! (qnan == 42));
00256     CHECK_COND(! (qnan == qnan));
00257     CHECK_COND(qnan != 42);
00258     CHECK_COND(qnan != qnan);
00259 
00260     /* The following tests may cause arithmetic traps.
00261     * CHECK_COND(! (qnan < 42));
00262     * CHECK_COND(! (qnan > 42));
00263     * CHECK_COND(! (qnan <= 42));
00264     * CHECK_COND(! (qnan >= 42));
00265     */
00266   }
00267   return true;
00268 }
00269 
00270 
00271 class ArbitraryType
00272 {};
00273 
00274 void LimitTest::test() {
00275   CPPUNIT_CHECK(test_integral_limits_base(bool()));
00276   CPPUNIT_CHECK(test_integral_limits(char()));
00277   typedef signed char signed_char;
00278   CPPUNIT_CHECK(test_signed_integral_limits(signed_char()));
00279   typedef unsigned char unsigned_char;
00280   CPPUNIT_CHECK(test_unsigned_integral_limits(unsigned_char()));
00281 #  if defined (_STLP_HAS_WCHAR_T) && !defined (_STLP_WCHAR_T_IS_USHORT)
00282   CPPUNIT_CHECK(test_integral_limits(wchar_t()));
00283 #  endif
00284   CPPUNIT_CHECK(test_signed_integral_limits(short()));
00285   typedef unsigned short unsigned_short;
00286   CPPUNIT_CHECK(test_unsigned_integral_limits(unsigned_short()));
00287   CPPUNIT_CHECK(test_signed_integral_limits(int()));
00288   typedef unsigned int unsigned_int;
00289   CPPUNIT_CHECK(test_unsigned_integral_limits(unsigned_int()));
00290   CPPUNIT_CHECK(test_signed_integral_limits(long()));
00291   typedef unsigned long unsigned_long;
00292   CPPUNIT_CHECK(test_unsigned_integral_limits(unsigned_long()));
00293 #  if defined (_STLP_LONG_LONG)
00294   typedef _STLP_LONG_LONG long_long;
00295   CPPUNIT_CHECK(test_signed_integral_limits(long_long()));
00296   typedef unsigned _STLP_LONG_LONG unsigned_long_long;
00297   CPPUNIT_CHECK(test_unsigned_integral_limits(unsigned_long_long()));
00298 #endif
00299 
00300   CPPUNIT_CHECK(test_float_limits(float()));
00301   CPPUNIT_CHECK(test_float_limits(double()));
00302 #  if !defined ( _STLP_NO_LONG_DOUBLE )
00303   typedef long double long_double;
00304   CPPUNIT_CHECK(test_float_limits(long_double()));
00305 #  endif
00306 
00307   CPPUNIT_ASSERT( !numeric_limits<ArbitraryType>::is_specialized );
00308 }
00309 
00310 void LimitTest::qnan_test() {
00311   CPPUNIT_CHECK(test_qnan(float()));
00312   CPPUNIT_CHECK(test_qnan(double()));
00313 #  if !defined ( _STLP_NO_LONG_DOUBLE )
00314   typedef long double long_double;
00315   CPPUNIT_CHECK(test_qnan(long_double()));
00316 #  endif
00317 }

Generated on Sun May 27 2012 04:35:28 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.