177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner/* boost limits_test.cpp   test your <limits> file for important
277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner *
377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner * Copyright Jens Maurer 2000
477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner * Permission to use, copy, modify, sell, and distribute this software
577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner * is hereby granted without fee provided that the above copyright notice
677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner * appears in all copies and that both that copyright notice and this
777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner * permission notice appear in supporting documentation,
877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner *
977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner * Jens Maurer makes no representations about the suitability of this
1077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner * software for any purpose. It is provided "as is" without express or
1177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner * implied warranty.
1277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner *
1377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner */
1477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner
1577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner#include <limits>
1677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner//#include <sstream>
1777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner
1877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner#include "cppunit/cppunit_proxy.h"
1977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner
2077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner#if !defined (STLPORT) || defined(_STLP_USE_NAMESPACES)
2177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turnerusing namespace std;
2277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner#endif
2377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner
2477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner//
2577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner// TestCase class
2677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner//
2777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turnerclass LimitTest : public CPPUNIT_NS::TestCase
2877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner{
2977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner  CPPUNIT_TEST_SUITE(LimitTest);
3077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner#  if defined (__BORLANDC__)
3177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner  /* Ignore FPU exceptions, set FPU precision to 64 bits */
3277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner  unsigned int _float_control_word = _control87(0, 0);
3377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner  _control87(PC_64|MCW_EM|IC_AFFINE, MCW_PC|MCW_EM|MCW_IC);
3477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner#  endif
3577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner  CPPUNIT_TEST(test);
3677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner  CPPUNIT_TEST(qnan_test);
3777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner#  if defined (__BORLANDC__)
3877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner  /* Reset floating point control word */
3977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner  _clear87();
4077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner  _control87(_float_control_word, MCW_PC|MCW_EM|MCW_IC);
4177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner#  endif
4277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner  CPPUNIT_TEST_SUITE_END();
4377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner
4477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turnerprotected:
4577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner  void test();
4677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner  void qnan_test();
4777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner};
4877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner
4977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' TurnerCPPUNIT_TEST_SUITE_REGISTRATION(LimitTest);
5077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner
5177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner#if defined (STLPORT) && defined (_STLP_STATIC_CONST_INIT_BUG)
5277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner#  define CHECK_COND(X) if (!(X))  { CPPUNIT_MESSAGE(#X); return false; }
5377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner#else
5477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner//This version force to have external linkage on static constant which might
5577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner//reveal that _STLP_NO_STATIC_CONST_DEFINITION should be commented.
5677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turnerbool check_cond(const bool& cond) { return cond; }
5777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner#  define CHECK_COND(X) if (!check_cond(X)) { CPPUNIT_MESSAGE(#X); return false; }
5877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner#endif
5977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner
6077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turnerbool valid_sign_info(bool, bool)
6177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner{ return true; }
6277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner
6377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turnertemplate <class _Tp>
6477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turnerbool valid_sign_info(bool limit_is_signed, const _Tp &) {
6577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner  return (limit_is_signed && _Tp(-1) < 0) ||
6677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner         (!limit_is_signed && _Tp(-1) > 0);
6777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner}
6877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner
6977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turnertemplate <class _Tp>
7077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turnerbool test_integral_limits_base(const _Tp &, bool unknown_sign = true, bool is_signed = true) {
7177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner  typedef numeric_limits<_Tp> lim;
7277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner
7377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner  CHECK_COND(lim::is_specialized);
7477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner  CHECK_COND(lim::is_exact);
7577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner  CHECK_COND(lim::is_integer);
7677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner  CHECK_COND(!lim::is_iec559);
7777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner  CHECK_COND(lim::min() < lim::max());
7877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner  CHECK_COND((unknown_sign && ((lim::is_signed && (lim::min() != 0)) || (!lim::is_signed && (lim::min() == 0)))) ||
7977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner             (!unknown_sign && ((lim::is_signed && is_signed) || (!lim::is_signed && !is_signed))));
8077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner
8177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner  if (unknown_sign) {
8277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner    CHECK_COND(valid_sign_info(lim::is_signed, _Tp()));
8377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner  }
8477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner  return true;
8577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner}
8677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner
8777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turnertemplate <class _Tp>
8877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turnerbool test_integral_limits(const _Tp &val, bool unknown_sign = true, bool is_signed = true) {
8977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner  if (!test_integral_limits_base(val, unknown_sign, is_signed))
9077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner    return false;
9177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner
9277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner  typedef numeric_limits<_Tp> lim;
9377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner
9477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner  CHECK_COND(lim::is_modulo);
9577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner
9677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner  if (lim::is_bounded ||
9777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner     (!lim::is_bounded && !lim::is_signed)) {
9877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner    _Tp tmp = lim::min();
9977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner    CHECK_COND( --tmp > lim::min() );
10077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner  }
10177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner
10277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner  if (lim::is_bounded) {
10377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner    _Tp tmp = lim::max();
10477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner    CHECK_COND( ++tmp < lim::max() );
10577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner  }
10677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner
10777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner  return true;
10877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner}
10977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner
11077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turnertemplate <class _Tp>
11177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turnerbool test_signed_integral_limits(const _Tp &__val) {
11277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner  return test_integral_limits(__val, false, true);
11377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner}
11477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turnertemplate <class _Tp>
11577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turnerbool test_unsigned_integral_limits(const _Tp &__val) {
11677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner  return test_integral_limits(__val, false, false);
11777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner}
11877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner
11977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turnertemplate <class _Tp>
12077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turnerbool test_float_values(_Tp lhs, _Tp rhs)
12177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner{ return lhs == rhs; }
12277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner
12377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turnertemplate <class _Tp>
12477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turnerbool test_float_limits(const _Tp &) {
12577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner  typedef numeric_limits<_Tp> lim;
12677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner  CHECK_COND(lim::is_specialized);
12777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner  CHECK_COND(!lim::is_modulo);
12877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner  CHECK_COND(!lim::is_integer);
12977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner  CHECK_COND(lim::is_signed);
13077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner
13177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner  CHECK_COND(lim::max() > 1000);
13277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner  CHECK_COND(lim::min() > 0);
13377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner  CHECK_COND(lim::min() < 0.001);
13477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner  CHECK_COND(lim::epsilon() > 0);
13577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner
13677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner  if (lim::is_iec559) {
13777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner    CHECK_COND(lim::has_infinity);
13877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner    CHECK_COND(lim::has_quiet_NaN);
13977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner    CHECK_COND(lim::has_signaling_NaN);
14077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner    CHECK_COND(lim::has_denorm == denorm_present);
14177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner  }
14277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner
14377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner  if (lim::has_denorm == denorm_absent) {
14477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner    CHECK_COND(lim::denorm_min() == lim::min());
14577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner    _Tp tmp = lim::min();
14677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner    tmp /= 2;
14777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner    if (tmp > 0 && tmp < lim::min()) {
14877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner      // has_denorm could be denorm_present
14977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner      CPPUNIT_MESSAGE("It looks like your compiler/platform supports denormalized floating point representation.");
15077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner    }
15177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner  }
15277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner  else if (lim::has_denorm == denorm_present) {
15377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner    CHECK_COND(lim::denorm_min() > 0);
15477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner    CHECK_COND(lim::denorm_min() < lim::min());
15577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner
15677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner    _Tp tmp = lim::min();
15777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner    while (tmp != 0) {
15877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner      _Tp old_tmp = tmp;
15977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner      tmp /= 2;
16077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner      CHECK_COND(tmp < old_tmp);
16177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner      CHECK_COND(tmp >= lim::denorm_min() || tmp == (_Tp)0);
16277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner      //ostringstream str;
16377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner      //str << "denorm_min = " << lim::denorm_min() << ", tmp = " << tmp;
16477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner      //CPPUNIT_MESSAGE(str.str().c_str());
16577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner    }
16677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner  }
16777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner
16877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner  if (lim::has_infinity) {
16977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner    const _Tp infinity = lim::infinity();
17077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner    /* Make sure those values are not 0 or similar nonsense.
17177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner     * Infinity must compare as if larger than the maximum representable value. */
17277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner
17377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner    _Tp val = lim::max();
17477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner    val *= 2;
17577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner
17677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner    /* We use test_float_values because without it some compilers (gcc) perform weird
17777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner     * optimization on the test giving unexpected result. */
17877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner    CHECK_COND(test_float_values(val, infinity));
17977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner
18077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner    /*
18177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner    ostringstream str;
18277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner    str << "lim::max() = " << lim::max() << ", val = " << val << ", infinity = " << infinity;
18377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner    CPPUNIT_MESSAGE( str.str().c_str() );
18477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner    str.str(string());
18577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner    str << "sizeof(_Tp) = " << sizeof(_Tp);
18677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner    CPPUNIT_MESSAGE( str.str().c_str() );
18777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner    if (sizeof(_Tp) == 4) {
18877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner      str.str(string());
18977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner      str << "val in hexa: " << showbase << hex << *((const unsigned int*)&val);
19077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner      str << ", infinity in hexa: " << showbase << hex << *((const unsigned int*)&infinity);
19177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner    }
19277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner#if defined (_STLP_LONG_LONG)
19377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner    else if (sizeof(_Tp) == sizeof(_STLP_LONG_LONG)) {
19477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner      str.str(string());
19577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner      str << "val in hexa: " << showbase << hex << *((const unsigned _STLP_LONG_LONG*)&val);
19677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner      str << ", infinity in hexa: " << showbase << hex << *((const unsigned _STLP_LONG_LONG*)&infinity);
19777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner    }
19877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner#endif
19977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner    else {
20077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner      str.str(string());
20177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner      str << "val: ";
20277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner      for (int i = 0; i != sizeof(_Tp) /  sizeof(unsigned short); ++i) {
20377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner        if (i != 0) str << ' ';
20477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner        str << showbase << hex << setw(4) << setfill('0') << *((const unsigned short*)&val + i);
20577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner      }
20677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner      str << ", infinity: ";
20777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner      for (int i = 0; i != sizeof(_Tp) /  sizeof(unsigned short); ++i) {
20877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner        if (i != 0) str << ' ';
20977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner        str << showbase << hex << setw(4) << setfill('0') << *((const unsigned short*)&infinity + i);
21077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner      }
21177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner    }
21277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner    CPPUNIT_MESSAGE( str.str().c_str() );
21377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner    str.str(string());
21477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner    str << dec;
21577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner    str << "lim::digits = " << lim::digits << ", lim::digits10 = " << lim::digits10 << endl;
21677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner    str << "lim::min_exponent = " << lim::min_exponent << ", lim::min_exponent10 = " << lim::min_exponent10 << endl;
21777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner    str << "lim::max_exponent = " << lim::max_exponent << ", lim::max_exponent10 = " << lim::max_exponent10 << endl;
21877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner    CPPUNIT_MESSAGE( str.str().c_str() );
21977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner    */
22077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner
22177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner    CHECK_COND(infinity == infinity);
22277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner    CHECK_COND(infinity > lim::max());
22377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner    CHECK_COND(-infinity < -lim::max());
22477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner  }
22577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner
22677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner  return true;
22777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner}
22877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner
22977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner//float generate_nan(float f) {
23077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner//  return 0.0f / f;
23177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner//}
23277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turnertemplate <class _Tp>
23377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turnerbool test_qnan(const _Tp &) {
23477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner  typedef numeric_limits<_Tp> lim;
23577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner  if (lim::has_quiet_NaN) {
23677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner    const _Tp qnan = lim::quiet_NaN();
23777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner
23877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner    //if (sizeof(_Tp) == 4) {
23977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner    //  ostringstream str;
24077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner    //  str << "qnan " << qnan << ", in hexa: " << showbase << hex << *((unsigned int*)&qnan);
24177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner    //  CPPUNIT_MESSAGE( str.str().c_str() );
24277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner    //  str.str("");
24377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner    //  float val = generate_nan(0.0f);
24477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner    //  str << "val " << val << ", in hexa: " << showbase << hex << *((unsigned int*)&val);
24577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner    //  CPPUNIT_MESSAGE( str.str().c_str() );
24677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner    //  str.str("");
24777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner    //  val = -qnan;
24877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner    //  str << "-qnan " << val << ", in hexa: " << showbase << hex << *((unsigned int*)&val);
24977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner    //  CPPUNIT_MESSAGE( str.str().c_str() );
25077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner    //}
25177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner    /* NaNs shall always compare "false" when compared for equality
25277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner    * If one of these fail, your compiler may be optimizing incorrectly,
25377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner    * or the STLport is incorrectly configured.
25477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner    */
25577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner    CHECK_COND(! (qnan == 42));
25677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner    CHECK_COND(! (qnan == qnan));
25777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner    CHECK_COND(qnan != 42);
25877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner    CHECK_COND(qnan != qnan);
25977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner
26077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner    /* The following tests may cause arithmetic traps.
26177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner    * CHECK_COND(! (qnan < 42));
26277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner    * CHECK_COND(! (qnan > 42));
26377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner    * CHECK_COND(! (qnan <= 42));
26477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner    * CHECK_COND(! (qnan >= 42));
26577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner    */
26677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner  }
26777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner  return true;
26877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner}
26977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner
27077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner
27177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turnerclass ArbitraryType
27277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner{};
27377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner
27477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turnervoid LimitTest::test() {
27577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner  CPPUNIT_CHECK(test_integral_limits_base(bool()));
27677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner  CPPUNIT_CHECK(test_integral_limits(char()));
27777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner  typedef signed char signed_char;
27877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner  CPPUNIT_CHECK(test_signed_integral_limits(signed_char()));
27977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner  typedef unsigned char unsigned_char;
28077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner  CPPUNIT_CHECK(test_unsigned_integral_limits(unsigned_char()));
281016fa0b146c592b1c527edfc9d317ced5d579de6Lai Wei-Chih#  if (defined (_STLP_HAS_WCHAR_T) && !defined (_STLP_WCHAR_T_IS_USHORT)) && WCHAR_MIN != 0 && !defined(__arm__)
2823112b24636bcd1051c6ff20bc49e4af3f0945e2fAndrew Hsieh /* wchar_t is unsigned in arm */
28377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner  CPPUNIT_CHECK(test_integral_limits(wchar_t()));
28477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner#  endif
28577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner  CPPUNIT_CHECK(test_signed_integral_limits(short()));
28677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner  typedef unsigned short unsigned_short;
28777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner  CPPUNIT_CHECK(test_unsigned_integral_limits(unsigned_short()));
28877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner  CPPUNIT_CHECK(test_signed_integral_limits(int()));
28977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner  typedef unsigned int unsigned_int;
29077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner  CPPUNIT_CHECK(test_unsigned_integral_limits(unsigned_int()));
29177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner  CPPUNIT_CHECK(test_signed_integral_limits(long()));
29277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner  typedef unsigned long unsigned_long;
29377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner  CPPUNIT_CHECK(test_unsigned_integral_limits(unsigned_long()));
29477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner#  if defined (_STLP_LONG_LONG)
29577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner  typedef _STLP_LONG_LONG long_long;
29677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner  CPPUNIT_CHECK(test_signed_integral_limits(long_long()));
29777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner  typedef unsigned _STLP_LONG_LONG unsigned_long_long;
29877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner  CPPUNIT_CHECK(test_unsigned_integral_limits(unsigned_long_long()));
29977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner#endif
30077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner
30177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner  CPPUNIT_CHECK(test_float_limits(float()));
30277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner  CPPUNIT_CHECK(test_float_limits(double()));
30377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner#  if !defined ( _STLP_NO_LONG_DOUBLE )
30477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner  typedef long double long_double;
30577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner  CPPUNIT_CHECK(test_float_limits(long_double()));
30677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner#  endif
30777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner
30877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner  CPPUNIT_ASSERT( !numeric_limits<ArbitraryType>::is_specialized );
30977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner}
31077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner
31177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turnervoid LimitTest::qnan_test() {
31277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner  CPPUNIT_CHECK(test_qnan(float()));
31377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner  CPPUNIT_CHECK(test_qnan(double()));
31477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner#  if !defined ( _STLP_NO_LONG_DOUBLE )
31577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner  typedef long double long_double;
31677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner  CPPUNIT_CHECK(test_qnan(long_double()));
31777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner#  endif
31877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner}
319