Home | History | Annotate | Download | only in unit
      1 #include <limits>
      2 
      3 #if !defined (STLPORT) || !defined (_STLP_USE_NO_IOSTREAMS)
      4 #  include <iomanip>
      5 #  include <string>
      6 #  include <sstream>
      7 #  include <cstdio>
      8 /*
      9 #  include <iostream>
     10 #  include <ieee754.h>
     11 */
     12 
     13 #  include "complete_digits.h"
     14 #  include "cppunit/cppunit_proxy.h"
     15 
     16 #  if !defined (STLPORT) || defined(_STLP_USE_NAMESPACES)
     17 using namespace std;
     18 #  endif
     19 
     20 //
     21 // TestCase class
     22 //
     23 class NumPutGetTest : public CPPUNIT_NS::TestCase
     24 {
     25   CPPUNIT_TEST_SUITE(NumPutGetTest);
     26 #  if defined (__BORLANDC__)
     27   /* Ignore FPU exceptions, set FPU precision to 64 bits */
     28   unsigned int _float_control_word = _control87(0, 0);
     29   _control87(PC_64|MCW_EM|IC_AFFINE, MCW_PC|MCW_EM|MCW_IC);
     30 #  endif
     31   CPPUNIT_TEST(num_put_float);
     32   CPPUNIT_TEST(num_put_integer);
     33   CPPUNIT_TEST(num_get_float);
     34   CPPUNIT_TEST(num_get_integer);
     35   CPPUNIT_TEST(inhex);
     36   CPPUNIT_TEST(pointer);
     37   CPPUNIT_TEST(fix_float_long);
     38   CPPUNIT_TEST(custom_numpunct);
     39 #  if defined (__BORLANDC__)
     40   /* Reset floating point control word */
     41   _clear87();
     42   _control87(_float_control_word, MCW_PC|MCW_EM|MCW_IC);
     43 #  endif
     44   CPPUNIT_TEST_SUITE_END();
     45 
     46 private:
     47   void num_put_float();
     48   void num_put_integer();
     49   void num_get_float();
     50   void num_get_integer();
     51   void inhex();
     52   void pointer();
     53   void fix_float_long();
     54   void custom_numpunct();
     55 
     56   static bool check_float(float val, float ref)
     57   {
     58     float epsilon = numeric_limits<float>::epsilon();
     59     return val <= ref + epsilon && val >= ref - epsilon;
     60   }
     61 
     62   static bool check_double(double val, double ref)
     63   {
     64     double epsilon = numeric_limits<double>::epsilon();
     65     return val <= ref + epsilon && val >= ref - epsilon;
     66   }
     67 
     68   static string reset_stream(ostringstream &ostr)
     69   {
     70     string tmp = ostr.str();
     71     ostr.str("");
     72     return tmp;
     73   }
     74 
     75 #if !defined (STLPORT) || !defined (_STLP_NO_MEMBER_TEMPLATES)
     76   template <class F>
     77   void check_get_float( F v )
     78   {
     79     F in_val_d = v;
     80     typedef numeric_limits<F> limits;
     81     {
     82       stringstream str;
     83 
     84       str << "1E+" << limits::max_exponent10;
     85 
     86       str >> in_val_d;
     87       CPPUNIT_ASSERT(!str.fail());
     88       CPPUNIT_ASSERT(str.eof());
     89       CPPUNIT_CHECK( in_val_d == in_val_d );
     90       CPPUNIT_CHECK( in_val_d != limits::infinity() );
     91     }
     92     {
     93       stringstream str;
     94 
     95       str << "-1E+" << limits::max_exponent10;
     96 
     97       str >> in_val_d;
     98       CPPUNIT_ASSERT(!str.fail());
     99       CPPUNIT_ASSERT(str.eof());
    100       CPPUNIT_CHECK( in_val_d == in_val_d );
    101       CPPUNIT_CHECK( in_val_d != -limits::infinity() );
    102     }
    103     {
    104       stringstream str;
    105 
    106       str << "1E" << limits::min_exponent10;
    107 
    108       str >> in_val_d;
    109       CPPUNIT_ASSERT(!str.fail());
    110       CPPUNIT_ASSERT(str.eof());
    111       CPPUNIT_CHECK( in_val_d == in_val_d );
    112       CPPUNIT_CHECK( in_val_d != F(0.0) );
    113     }
    114     {
    115       stringstream str;
    116 
    117       str << "1E+" << (limits::max_exponent10 + 1);
    118 
    119       str >> in_val_d;
    120       CPPUNIT_ASSERT(!str.fail());
    121       CPPUNIT_ASSERT(str.eof());
    122       CPPUNIT_CHECK( in_val_d == in_val_d );
    123       CPPUNIT_CHECK( in_val_d == limits::infinity() );
    124     }
    125     {
    126       stringstream str;
    127 
    128       str << "-1E+" << (limits::max_exponent10 + 1);
    129 
    130       str >> in_val_d;
    131       CPPUNIT_ASSERT(!str.fail());
    132       CPPUNIT_ASSERT(str.eof());
    133       CPPUNIT_CHECK( in_val_d == in_val_d );
    134       CPPUNIT_CHECK( in_val_d == -limits::infinity() );
    135     }
    136     {
    137       stringstream str;
    138 
    139       str << "1E" << (limits::min_exponent10 - 1);
    140 
    141       str >> in_val_d;
    142       CPPUNIT_ASSERT(!str.fail());
    143       CPPUNIT_ASSERT(str.eof());
    144       CPPUNIT_CHECK( in_val_d == in_val_d );
    145       CPPUNIT_CHECK( in_val_d >= F(0.0) && in_val_d <= limits::min() );
    146     }
    147 #if !defined (__MINGW32__)
    148     {
    149       stringstream str;
    150 
    151       str << limits::max();
    152 
    153       CPPUNIT_ASSERT(!str.fail());
    154       CPPUNIT_CHECK( str.str() != "inf" );
    155       CPPUNIT_CHECK( str.str() != "-inf" );
    156       CPPUNIT_CHECK( str.str() != "nan" );
    157       CPPUNIT_CHECK( str.str() != "-nan" );
    158       //CPPUNIT_MESSAGE( str.str().c_str() );
    159 
    160       //str.str("");
    161       //str << limits::max_exponent10;
    162       //CPPUNIT_MESSAGE( str.str().c_str() );
    163 
    164       str >> in_val_d;
    165 
    166       CPPUNIT_ASSERT(!str.fail());
    167       CPPUNIT_ASSERT(str.eof());
    168       CPPUNIT_CHECK( in_val_d == in_val_d );
    169       CPPUNIT_CHECK( in_val_d != limits::infinity() );
    170     }
    171     {
    172       stringstream str;
    173 
    174       str << fixed << limits::max();
    175 
    176       CPPUNIT_ASSERT(!str.fail());
    177       CPPUNIT_CHECK( str.str() != "inf" );
    178       CPPUNIT_CHECK( str.str() != "-inf" );
    179       CPPUNIT_CHECK( str.str() != "nan" );
    180       CPPUNIT_CHECK( str.str() != "-nan" );
    181       //CPPUNIT_MESSAGE( str.str().c_str() );
    182 
    183       //str.str("");
    184       //str << limits::max_exponent10;
    185       //CPPUNIT_MESSAGE( str.str().c_str() );
    186 
    187       str >> in_val_d;
    188 
    189       CPPUNIT_ASSERT(!str.fail());
    190       CPPUNIT_ASSERT(str.eof());
    191       CPPUNIT_CHECK( in_val_d == in_val_d );
    192       CPPUNIT_CHECK( in_val_d != limits::infinity() );
    193     }
    194     {
    195       stringstream str;
    196 
    197       str << scientific << setprecision(50) << limits::max();
    198 
    199       CPPUNIT_ASSERT(!str.fail());
    200       CPPUNIT_CHECK( str.str() != "inf" );
    201       CPPUNIT_CHECK( str.str() != "-inf" );
    202       CPPUNIT_CHECK( str.str() != "nan" );
    203       CPPUNIT_CHECK( str.str() != "-nan" );
    204       //CPPUNIT_MESSAGE( str.str().c_str() );
    205 
    206       //str.str("");
    207       //str << limits::max_exponent10;
    208       //CPPUNIT_MESSAGE( str.str().c_str() );
    209 
    210       str >> in_val_d;
    211 
    212       CPPUNIT_ASSERT(!str.fail());
    213       CPPUNIT_ASSERT(str.eof());
    214       CPPUNIT_CHECK( in_val_d == in_val_d );
    215       CPPUNIT_CHECK( in_val_d != limits::infinity() );
    216     }
    217 #endif
    218     {
    219       stringstream str;
    220 
    221       str << limits::infinity();
    222 
    223       CPPUNIT_ASSERT( !str.fail() );
    224       CPPUNIT_ASSERT( !limits::has_infinity || str.str() == "inf" );
    225     }
    226     {
    227       stringstream str;
    228 
    229       str << -limits::infinity();
    230 
    231       CPPUNIT_ASSERT( !str.fail() );
    232       CPPUNIT_ASSERT( !limits::has_infinity || str.str() == "-inf" );
    233     }
    234     {
    235       stringstream str;
    236 
    237       str << limits::quiet_NaN();
    238 
    239       CPPUNIT_ASSERT( !str.fail() );
    240       CPPUNIT_ASSERT( !limits::has_quiet_NaN || str.str() == "nan" );
    241     }
    242     {
    243       stringstream str;
    244 
    245       str << -limits::quiet_NaN();
    246 
    247       CPPUNIT_ASSERT( !str.fail() );
    248       CPPUNIT_ASSERT( !limits::has_quiet_NaN || str.str() == "-nan" );
    249     }
    250     {
    251       stringstream str;
    252 
    253       str << "0." << string(limits::max_exponent10, '0') << "1e" << (limits::max_exponent10 + 1);
    254       CPPUNIT_ASSERT( !str.fail() );
    255 
    256       str >> in_val_d;
    257       CPPUNIT_ASSERT( !str.fail() );
    258       CPPUNIT_ASSERT( str.eof() );
    259       CPPUNIT_CHECK( in_val_d == 1 );
    260     }
    261     {
    262       stringstream str;
    263 
    264       str << "1" << string(-(limits::min_exponent10 - 1), '0') << "e" << (limits::min_exponent10 - 1);
    265       CPPUNIT_ASSERT( !str.fail() );
    266 
    267       str >> in_val_d;
    268       CPPUNIT_ASSERT( !str.fail() );
    269       CPPUNIT_ASSERT( str.eof() );
    270       CPPUNIT_CHECK( in_val_d == 1 );
    271     }
    272 #  if defined (_STLPORT_VERSION) && (_STLPORT_VERSION >= 0x530)
    273     // The following tests are showing that simply changing stream
    274     // precision lead to different result. Do not seems to be a real
    275     // problem, simply rounding approximation but additional study should
    276     // be done after 5.2 release.
    277     {
    278       stringstream str;
    279       str << setprecision(limits::digits10 + 2) << limits::max();
    280 
    281       CPPUNIT_MESSAGE(str.str().c_str());
    282       CPPUNIT_ASSERT( !str.fail() );
    283 
    284       F val;
    285       str >> val;
    286 
    287       CPPUNIT_ASSERT( !str.fail() );
    288       CPPUNIT_ASSERT( limits::infinity() > val );
    289     }
    290     {
    291       stringstream str;
    292       str << setprecision(limits::digits10 + 1) << limits::max();
    293 
    294       CPPUNIT_MESSAGE(str.str().c_str());
    295       CPPUNIT_ASSERT( !str.fail() );
    296 
    297       F val;
    298       str >> val;
    299 
    300       CPPUNIT_ASSERT( !str.fail() );
    301       CPPUNIT_ASSERT( limits::infinity() > val );
    302     }
    303 #  endif
    304   }
    305 #else
    306 #  define __check_get_float( F ) \
    307   void check_get_float( F v ) \
    308   { \
    309     F in_val_d = v; \
    310     { \
    311       stringstream str; \
    312  \
    313       str << "1E+" << numeric_limits<F>::max_exponent10; \
    314  \
    315       str >> in_val_d; \
    316       CPPUNIT_ASSERT(!str.fail()); \
    317       CPPUNIT_ASSERT(str.eof()); \
    318       CPPUNIT_CHECK( in_val_d == in_val_d ); \
    319       CPPUNIT_CHECK( in_val_d != numeric_limits<F>::infinity() ); \
    320     } \
    321     { \
    322       stringstream str; \
    323  \
    324       str << "-1E+" << numeric_limits<F>::max_exponent10; \
    325  \
    326       str >> in_val_d; \
    327       CPPUNIT_ASSERT(!str.fail()); \
    328       CPPUNIT_ASSERT(str.eof()); \
    329       CPPUNIT_CHECK( in_val_d == in_val_d ); \
    330       CPPUNIT_CHECK( in_val_d != -numeric_limits<F>::infinity() ); \
    331     } \
    332     { \
    333       stringstream str; \
    334  \
    335       str << "1E" << numeric_limits<F>::min_exponent10; \
    336  \
    337       str >> in_val_d; \
    338       CPPUNIT_ASSERT(!str.fail()); \
    339       CPPUNIT_ASSERT(str.eof()); \
    340       CPPUNIT_CHECK( in_val_d == in_val_d ); \
    341       CPPUNIT_CHECK( in_val_d != F(0.0) ); \
    342     } \
    343     { \
    344       stringstream str; \
    345  \
    346       str << "1E+" << (numeric_limits<F>::max_exponent10 + 1); \
    347  \
    348       str >> in_val_d; \
    349       CPPUNIT_ASSERT(!str.fail()); \
    350       CPPUNIT_ASSERT(str.eof()); \
    351       CPPUNIT_CHECK( in_val_d == in_val_d ); \
    352       CPPUNIT_CHECK( in_val_d == numeric_limits<F>::infinity() ); \
    353     } \
    354     { \
    355       stringstream str; \
    356  \
    357       str << "-1E+" << (numeric_limits<F>::max_exponent10 + 1); \
    358  \
    359       str >> in_val_d; \
    360       CPPUNIT_ASSERT(!str.fail()); \
    361       CPPUNIT_ASSERT(str.eof()); \
    362       CPPUNIT_CHECK( in_val_d == in_val_d ); \
    363       CPPUNIT_CHECK( in_val_d == -numeric_limits<F>::infinity() ); \
    364     } \
    365     { \
    366       stringstream str; \
    367  \
    368       str << "1E" << (numeric_limits<F>::min_exponent10 - 1); \
    369  \
    370       str >> in_val_d; \
    371       CPPUNIT_ASSERT(!str.fail()); \
    372       CPPUNIT_ASSERT(str.eof()); \
    373       CPPUNIT_CHECK( in_val_d == in_val_d ); \
    374       CPPUNIT_CHECK( in_val_d >= F(0.0) && in_val_d <= numeric_limits<F>::min() ); \
    375     } \
    376   }
    377 
    378   __check_get_float( float )
    379   __check_get_float( double )
    380 #  if !defined (STLPORT) || !defined (_STLP_NO_LONG_DOUBLE)
    381   __check_get_float( long double )
    382 #  endif
    383 #  undef __check_get_float
    384 #endif // _STLP_NO_MEMBER_TEMPLATES
    385 };
    386 
    387 CPPUNIT_TEST_SUITE_REGISTRATION(NumPutGetTest);
    388 
    389 #if defined (_MSC_VER)
    390 #  pragma warning (disable : 4056)
    391 #  pragma warning (disable : 4756)
    392 #endif
    393 
    394 //
    395 // tests implementation
    396 //
    397 void NumPutGetTest::num_put_float()
    398 {
    399   {
    400     string output, digits;
    401 
    402     {
    403       ostringstream ostr;
    404       ostr << 1.23457e+17f;
    405       CPPUNIT_ASSERT(ostr.good());
    406       output = reset_stream(ostr);
    407       digits = "17";
    408       complete_digits(digits);
    409       CPPUNIT_CHECK(output == string("1.23457e+") + digits );
    410     }
    411 
    412     {
    413       ostringstream ostr;
    414       ostr << setprecision(200) << 1.23457e+17f;
    415       CPPUNIT_ASSERT(ostr.good());
    416       output = reset_stream(ostr);
    417       CPPUNIT_CHECK( output.size() < 200 );
    418     }
    419 
    420     {
    421       ostringstream ostr;
    422       ostr << setprecision(200) << numeric_limits<float>::min();
    423       CPPUNIT_ASSERT(ostr.good());
    424       output = reset_stream(ostr);
    425       CPPUNIT_CHECK( output.size() < 200 );
    426     }
    427 
    428     {
    429       ostringstream ostr;
    430       ostr << fixed << 1.23457e+17f;
    431       CPPUNIT_ASSERT(ostr.good());
    432       output = reset_stream(ostr);
    433       CPPUNIT_CHECK(output.size() == 25);
    434       CPPUNIT_CHECK(output.substr(0, 5) == "12345");
    435       CPPUNIT_CHECK(output.substr(18) == ".000000");
    436     }
    437 
    438     {
    439       ostringstream ostr;
    440       ostr << fixed << showpos << 1.23457e+17f;
    441       CPPUNIT_ASSERT(ostr.good());
    442       output = reset_stream(ostr);
    443       CPPUNIT_CHECK(output.size() == 26);
    444       CPPUNIT_CHECK(output.substr(0, 6) == "+12345");
    445       CPPUNIT_CHECK(output.substr(19) == ".000000");
    446     }
    447 
    448     {
    449       ostringstream ostr;
    450       ostr << fixed << showpos << setprecision(100) << 1.23457e+17f;
    451       CPPUNIT_ASSERT(ostr.good());
    452       output = reset_stream(ostr);
    453       CPPUNIT_CHECK(output.size() == 120);
    454       CPPUNIT_CHECK(output.substr(0, 6) == "+12345");
    455       CPPUNIT_CHECK(output.substr(19) == ".0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" );
    456     }
    457 
    458     {
    459       ostringstream ostr;
    460       ostr << scientific << setprecision(8) << 0.12345678f;
    461       CPPUNIT_ASSERT(ostr.good());
    462       output = reset_stream(ostr);
    463       digits = "1";
    464       complete_digits(digits);
    465       CPPUNIT_CHECK(output == string("1.23456780e-") + digits );
    466     }
    467 
    468     {
    469       ostringstream ostr;
    470       ostr << fixed << setprecision(8) << setw(30) << setfill('0') << 0.12345678f;
    471       CPPUNIT_ASSERT(ostr.good());
    472       output = reset_stream(ostr);
    473       CPPUNIT_CHECK(output == "000000000000000000000.12345678");
    474     }
    475 
    476     {
    477       ostringstream ostr;
    478       ostr << fixed << showpos << setprecision(8) << setw(30) << setfill('0') << 0.12345678f;
    479       CPPUNIT_ASSERT(ostr.good());
    480       output = reset_stream(ostr);
    481       CPPUNIT_CHECK(output == "0000000000000000000+0.12345678");
    482     }
    483 
    484     {
    485       ostringstream ostr;
    486       ostr << fixed << showpos << setprecision(8) << setw(30) << left << setfill('0') << 0.12345678f;
    487       CPPUNIT_ASSERT(ostr.good());
    488       output = reset_stream(ostr);
    489       CPPUNIT_CHECK(output == "+0.123456780000000000000000000");
    490     }
    491 
    492     {
    493       ostringstream ostr;
    494       ostr << fixed << showpos << setprecision(8) << setw(30) << internal << setfill('0') << 0.12345678f;
    495       CPPUNIT_ASSERT(ostr.good());
    496       output = reset_stream(ostr);
    497       CPPUNIT_CHECK(output == "+00000000000000000000.12345678");
    498     }
    499 
    500     {
    501       ostringstream ostr;
    502       ostr << fixed << showpos << setprecision(100) << 1.234567e+17;
    503       CPPUNIT_ASSERT(ostr.good());
    504       output = reset_stream(ostr);
    505       CPPUNIT_CHECK(output.size() == 120);
    506       CPPUNIT_CHECK(output.substr(0, 6) == "+12345");
    507       CPPUNIT_CHECK(output.substr(19) == ".0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" );
    508     }
    509 
    510 #if !defined (STLPORT) || !defined (_STLP_NO_LONG_DOUBLE)
    511     {
    512       ostringstream ostr;
    513       ostr << fixed << showpos << setprecision(100) << 1.234567e+17l;
    514       CPPUNIT_ASSERT(ostr.good());
    515       output = reset_stream(ostr);
    516       CPPUNIT_CHECK(output.size() == 120);
    517       CPPUNIT_CHECK(output.substr(0, 6) == "+12345");
    518       CPPUNIT_CHECK(output.substr(19) == ".0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" );
    519     }
    520 #endif
    521 
    522     {
    523       ostringstream ostr;
    524       ostr << scientific << setprecision(50) << 0.0;
    525       CPPUNIT_ASSERT(ostr.good());
    526       output = reset_stream(ostr);
    527       CPPUNIT_CHECK( output == "0.00000000000000000000000000000000000000000000000000e+00" );
    528     }
    529     {
    530       ostringstream ostr;
    531       ostr << fixed << setprecision(100) << numeric_limits<float>::max();
    532       CPPUNIT_ASSERT(ostr.good());
    533       output = reset_stream(ostr);
    534       //CPPUNIT_MESSAGE( output.c_str() );
    535     }
    536 
    537     {
    538       ostringstream ostr;
    539       ostr << setprecision(100) << numeric_limits<double>::max();
    540       CPPUNIT_ASSERT(ostr.good());
    541       output = reset_stream(ostr);
    542       //CPPUNIT_MESSAGE( output.c_str() );
    543     }
    544 
    545 #if !defined (STLPORT) || !defined (_STLP_NO_LONG_DOUBLE)
    546     {
    547       ostringstream ostr;
    548       ostr << setprecision(100) << numeric_limits<long double>::max();
    549       CPPUNIT_ASSERT(ostr.good());
    550       output = reset_stream(ostr);
    551       //CPPUNIT_MESSAGE( output.c_str() );
    552     }
    553 #endif
    554 
    555     //{
    556     //  ostringstream ostr;
    557     //  ostr << setprecision(-numeric_limits<float>::min_exponent10 + numeric_limits<float>::digits10 + 9) << numeric_limits<float>::min();
    558     //  CPPUNIT_ASSERT(ostr.good());
    559     //  output = reset_stream(ostr);
    560     //  //CPPUNIT_MESSAGE( output.c_str() );
    561     //}
    562 
    563     //{
    564     //  ostringstream ostr;
    565     //  ostr << setprecision(-numeric_limits<double>::min_exponent10 + numeric_limits<double>::digits10) << numeric_limits<double>::min();
    566     //  CPPUNIT_ASSERT(ostr.good());
    567     //  output = reset_stream(ostr);
    568     //  //CPPUNIT_MESSAGE( output.c_str() );
    569     //}
    570 
    571 //#if !defined (STLPORT) || !defined (_STLP_NO_LONG_DOUBLE)
    572 //    {
    573 //      ostringstream ostr;
    574 //      ostr << setprecision(-numeric_limits<long double>::min_exponent10 + numeric_limits<long double>::digits10) << numeric_limits<long double>::min();
    575 //      CPPUNIT_ASSERT(ostr.good());
    576 //      output = reset_stream(ostr);
    577 //      CPPUNIT_MESSAGE( output.c_str() );
    578 //    }
    579 //#endif
    580   }
    581 
    582   {
    583     ostringstream str;
    584 
    585     str.setf(ios::fixed, ios::floatfield);
    586     str << 1.0e+5;
    587     // cerr << str.str() << endl;
    588     CPPUNIT_CHECK( str.str() == "100000.000000" );
    589 
    590     reset_stream(str);
    591     str.precision(0);
    592     str << 1.0e+5;
    593     CPPUNIT_CHECK( str.str() == "100000" );
    594 
    595     reset_stream(str);
    596     str.precision(4);
    597     str << 1.0e+5;
    598     CPPUNIT_CHECK( str.str() == "100000.0000" );
    599 
    600     reset_stream(str);
    601     str.precision(0);
    602     str << 1.0e+83;
    603     CPPUNIT_CHECK( str.str().size() == 84 );
    604     //printf("\nC result: %.0f\n", 1.0e+83);
    605     //CPPUNIT_MESSAGE( str.str().c_str() );
    606     //CPPUNIT_CHECK( str.str() == "100000000000000000000000000000000000000000000000000000000000000000000000000000000000" );
    607 
    608     // cerr.setf(ios::fixed, ios::floatfield);
    609     // cerr << DBL_MAX << endl;
    610     // cerr << 1.0e+37 << endl;
    611   }
    612 }
    613 
    614 #define CHECK_COMPLETE(type, val, base, showbase, showpos, casing, width, adjust, expected) \
    615 { \
    616   type tmp = val; \
    617   ostringstream ostr; \
    618   ostr << base << showbase << showpos << casing << setw(width) << adjust << tmp; \
    619   CPPUNIT_CHECK( ostr.str() == expected ); \
    620 }
    621 
    622 #define CHECK(type, val, base, expected) \
    623   CHECK_COMPLETE(type, val, base, noshowbase, noshowpos, nouppercase, 0, right, expected)
    624 
    625 void NumPutGetTest::num_put_integer()
    626 {
    627   //octal outputs
    628   {
    629     CHECK(short, 0, oct, "0")
    630     CHECK(short, 1, oct, "1")
    631     CHECK(short, 12345, oct, "30071")
    632     if (sizeof(short) == 2) {
    633       CHECK(short, -1, oct, "177777")
    634       CHECK(short, -12345, oct, "147707")
    635     }
    636 
    637     CHECK(unsigned short, 0, oct, "0")
    638     CHECK(unsigned short, 12345, oct, "30071")
    639 
    640     CHECK(int, 0, oct, "0")
    641     CHECK(int, 12345678, oct, "57060516")
    642     if (sizeof(int) == 4) {
    643       CHECK(int, -1, oct, "37777777777")
    644       CHECK(int, -12345678, oct, "37720717262")
    645     }
    646 
    647     CHECK(unsigned int, 0, oct, "0")
    648     CHECK(unsigned int, 12345678, oct, "57060516")
    649 
    650     CHECK(long, 0, oct, "0")
    651     CHECK(long, 12345678, oct, "57060516")
    652     if (sizeof(long) == 4) {
    653       CHECK(long, -1, oct, "37777777777")
    654       CHECK(long, -12345678, oct, "37720717262")
    655     }
    656 
    657     CHECK(unsigned long, 0, oct, "0")
    658     CHECK(unsigned long, 12345678, oct, "57060516")
    659 
    660 #if defined (STLPORT) && defined (_STLP_LONG_LONG)
    661     CHECK(_STLP_LONG_LONG, 0, oct, "0")
    662     CHECK(_STLP_LONG_LONG, 12345678, oct, "57060516")
    663     if (sizeof(_STLP_LONG_LONG) == 8) {
    664       CHECK(_STLP_LONG_LONG, -1, oct, "1777777777777777777777")
    665       CHECK(_STLP_LONG_LONG, -12345678, oct, "1777777777777720717262")
    666     }
    667 
    668     CHECK(unsigned _STLP_LONG_LONG, 0, oct, "0")
    669     CHECK(unsigned _STLP_LONG_LONG, 12345678, oct, "57060516")
    670 #endif
    671 
    672     //Even with showbase, 0 value gives "0" (see printf documentation)
    673     CHECK_COMPLETE(short, 0, oct, showbase, noshowpos, nouppercase, 0, right, "0")
    674     CHECK_COMPLETE(short, 0, oct, showbase, showpos, nouppercase, 6, right, "     0")
    675 
    676     CHECK_COMPLETE(short, 1, oct, showbase, noshowpos, nouppercase, 6, right, "    01")
    677     CHECK_COMPLETE(short, 1, oct, showbase, noshowpos, nouppercase, 6, left, "01    ")
    678     CHECK_COMPLETE(short, 1, oct, showbase, showpos, nouppercase, 6, internal, "    01")
    679   }
    680 
    681   //decimal outputs
    682   {
    683     CHECK(short, 0, dec, "0")
    684     CHECK(short, -1, dec, "-1")
    685     CHECK(short, 12345, dec, "12345")
    686     CHECK(short, -12345, dec, "-12345")
    687 
    688     CHECK(unsigned short, 0, dec, "0")
    689     CHECK(unsigned short, 12345, dec, "12345")
    690 
    691     CHECK(int, 0, dec, "0")
    692     CHECK(int, -1, dec, "-1")
    693     CHECK(int, 12345678, dec, "12345678")
    694     CHECK(int, -12345678, dec, "-12345678")
    695 
    696     CHECK(unsigned int, 0, dec, "0")
    697     CHECK(unsigned int, 12345678, dec, "12345678")
    698 
    699     CHECK(long, 0, dec, "0")
    700     CHECK(long, -1, dec, "-1")
    701     CHECK(long, 12345678, dec, "12345678")
    702     CHECK(long, -12345678, dec, "-12345678")
    703 
    704     CHECK(unsigned long, 0, dec, "0")
    705     CHECK(unsigned long, 12345678, dec, "12345678")
    706 #if defined (STLPORT) && defined (_STLP_LONG_LONG)
    707     CHECK(_STLP_LONG_LONG, 0, dec, "0")
    708     CHECK(_STLP_LONG_LONG, -1, dec, "-1")
    709     CHECK(_STLP_LONG_LONG, 12345678, dec, "12345678")
    710     CHECK(_STLP_LONG_LONG, -12345678, dec, "-12345678")
    711 
    712     CHECK(unsigned _STLP_LONG_LONG, 0, dec, "0")
    713     CHECK(unsigned _STLP_LONG_LONG, 12345678, dec, "12345678")
    714 #endif
    715 
    716     CHECK_COMPLETE(short, 0, dec, showbase, showpos, nouppercase, 0, right, "+0")
    717     CHECK_COMPLETE(short, 0, dec, showbase, showpos, nouppercase, 6, right, "    +0")
    718     CHECK_COMPLETE(short, 1, dec, showbase, showpos, nouppercase, 6, right, "    +1")
    719     CHECK_COMPLETE(short, 1, dec, showbase, showpos, nouppercase, 6, left, "+1    ")
    720     CHECK_COMPLETE(short, 1, dec, showbase, showpos, nouppercase, 6, internal, "+    1")
    721   }
    722 
    723   //hexadecimal outputs
    724   {
    725     CHECK(short, 0, hex, "0")
    726     CHECK(short, 12345, hex, "3039")
    727     if (sizeof(short) == 2) {
    728       CHECK(short, -1, hex, "ffff")
    729       CHECK(short, -12345, hex, "cfc7")
    730     }
    731 
    732     CHECK(unsigned short, 0, hex, "0")
    733     CHECK(unsigned short, 12345, hex, "3039")
    734 
    735     CHECK(int, 0, hex, "0")
    736     CHECK(int, 12345678, hex, "bc614e")
    737     if (sizeof(int) == 4) {
    738       CHECK(int, -1, hex, "ffffffff")
    739       CHECK(int, -12345678, hex, "ff439eb2")
    740     }
    741 
    742     CHECK(unsigned int, 0, hex, "0")
    743     CHECK(unsigned int, 12345678, hex, "bc614e")
    744 
    745     CHECK(long, 0, hex, "0")
    746     CHECK(long, 12345678, hex, "bc614e")
    747     if (sizeof(long) == 4) {
    748       CHECK(long, -1, hex, "ffffffff")
    749       CHECK(long, -12345678, hex, "ff439eb2")
    750     }
    751 
    752     CHECK(unsigned long, 0, hex, "0")
    753     CHECK(unsigned long, 12345678, hex, "bc614e")
    754 #if defined (STLPORT) && defined (_STLP_LONG_LONG)
    755     CHECK(_STLP_LONG_LONG, 0, hex, "0")
    756     CHECK(_STLP_LONG_LONG, 12345678, hex, "bc614e")
    757     if (sizeof(_STLP_LONG_LONG) == 8) {
    758       CHECK(_STLP_LONG_LONG, -1, hex, "ffffffffffffffff")
    759       CHECK(_STLP_LONG_LONG, -12345678, hex, "ffffffffff439eb2")
    760     }
    761 
    762     CHECK(unsigned _STLP_LONG_LONG, 0, hex, "0")
    763     CHECK(unsigned _STLP_LONG_LONG, 12345678, hex, "bc614e")
    764 #endif
    765 
    766     //Even with showbase, 0 value gives "0" output (see printf documentation)
    767     CHECK_COMPLETE(short, 0, hex, showbase, showpos, nouppercase, 0, right, "0")
    768     CHECK_COMPLETE(short, 0, hex, showbase, noshowpos, nouppercase, 6, right, "     0")
    769     CHECK_COMPLETE(short, 0, hex, showbase, noshowpos, nouppercase, 6, internal, "     0")
    770 
    771     CHECK_COMPLETE(short, 1, hex, showbase, noshowpos, nouppercase, 6, right, "   0x1")
    772     CHECK_COMPLETE(short, 1, hex, showbase, noshowpos, nouppercase, 6, left, "0x1   ")
    773     CHECK_COMPLETE(short, 1, hex, showbase, noshowpos, nouppercase, 6, internal, "0x   1")
    774     CHECK_COMPLETE(short, 1, hex, showbase, noshowpos, uppercase, 6, left, "0X1   ")
    775     CHECK_COMPLETE(short, 1, hex, showbase, showpos, uppercase, 6, internal, "0X   1")
    776   }
    777 }
    778 
    779 void NumPutGetTest::num_get_float()
    780 {
    781   float in_val;
    782 
    783   istringstream istr;
    784 
    785   istr.str("1.2345");
    786   istr >> in_val;
    787   CPPUNIT_ASSERT(!istr.fail());
    788   CPPUNIT_ASSERT(istr.eof());
    789   CPPUNIT_ASSERT(check_float(in_val, 1.2345f));
    790   istr.clear();
    791 
    792   istr.str("-1.2345");
    793   istr >> in_val;
    794   CPPUNIT_ASSERT(!istr.fail());
    795   CPPUNIT_ASSERT(istr.eof());
    796   CPPUNIT_ASSERT(check_float(in_val, -1.2345f));
    797   istr.clear();
    798 
    799   istr.str("+1.2345");
    800   istr >> in_val;
    801   CPPUNIT_ASSERT(!istr.fail());
    802   CPPUNIT_ASSERT(check_float(in_val, 1.2345f));
    803   istr.clear();
    804 
    805   istr.str("000000000000001.234500000000");
    806   istr >> in_val;
    807   CPPUNIT_ASSERT(!istr.fail());
    808   CPPUNIT_ASSERT(istr.eof());
    809   CPPUNIT_ASSERT(check_float(in_val, 1.2345f));
    810   istr.clear();
    811 
    812   istr.str("1.2345e+04");
    813   istr >> in_val;
    814   CPPUNIT_ASSERT(!istr.fail());
    815   CPPUNIT_ASSERT(istr.eof());
    816   CPPUNIT_ASSERT(check_float(in_val, 12345.0f));
    817   istr.clear();
    818 
    819   CPPUNIT_MESSAGE( "float" );
    820   check_get_float( 0.0F );
    821   CPPUNIT_MESSAGE( "double" );
    822   check_get_float( 0.0 );
    823 #if !defined (STLPORT) || !defined (_STLP_NO_LONG_DOUBLE)
    824   CPPUNIT_MESSAGE( "long double" );
    825   check_get_float( 0.0L );
    826 #endif
    827   {
    828     stringstream str;
    829 
    830     str << "1e" << numeric_limits<double>::max_exponent10;
    831     CPPUNIT_ASSERT(!str.fail());
    832 
    833     float val;
    834     str >> val;
    835     CPPUNIT_ASSERT(!str.fail());
    836     CPPUNIT_ASSERT(str.eof());
    837     CPPUNIT_ASSERT( numeric_limits<double>::max_exponent10 <= numeric_limits<float>::max_exponent10 ||
    838                     val == numeric_limits<float>::infinity() );
    839   }
    840   {
    841     stringstream str;
    842 
    843     str << "1e" << numeric_limits<double>::min_exponent10;
    844     CPPUNIT_ASSERT(!str.fail());
    845 
    846     float val;
    847     str >> val;
    848     CPPUNIT_ASSERT(!str.fail());
    849     CPPUNIT_ASSERT(str.eof());
    850     CPPUNIT_ASSERT( numeric_limits<double>::min_exponent10 >= numeric_limits<float>::min_exponent10 ||
    851                     val == 0.0f );
    852   }
    853 #if !defined (STLPORT) || !defined (_STLP_NO_LONG_DOUBLE)
    854   {
    855     stringstream str;
    856 
    857     str << "1e" << numeric_limits<long double>::max_exponent10;
    858     CPPUNIT_ASSERT(!str.fail());
    859 
    860     double val;
    861     str >> val;
    862     CPPUNIT_ASSERT(!str.fail());
    863     CPPUNIT_ASSERT(str.eof());
    864     CPPUNIT_ASSERT( numeric_limits<long double>::max_exponent10 <= numeric_limits<double>::max_exponent10 ||
    865                     val == numeric_limits<double>::infinity() );
    866   }
    867   {
    868     stringstream str;
    869 
    870     str << "1e" << numeric_limits<long double>::min_exponent10;
    871     CPPUNIT_ASSERT(!str.fail());
    872 
    873     double val;
    874     str >> val;
    875     CPPUNIT_ASSERT(!str.fail());
    876     CPPUNIT_ASSERT(str.eof());
    877     CPPUNIT_ASSERT( numeric_limits<long double>::min_exponent10 >= numeric_limits<double>::min_exponent10 ||
    878                     val == 0.0 );
    879   }
    880   {
    881     const char* p = "2.718281828459045235360287471352662497757247093e0";
    882     std::stringstream s;
    883     s << p;
    884     long double x;
    885     s >> x;
    886     CPPUNIT_ASSERT( x > 2.70l && x < 2.72l );
    887   }
    888 #endif
    889 }
    890 
    891 void NumPutGetTest::num_get_integer()
    892 {
    893   //octal input
    894   {
    895     istringstream istr;
    896     istr.str("30071");
    897     short val;
    898     istr >> oct >> val;
    899     CPPUNIT_ASSERT( !istr.fail() );
    900     CPPUNIT_ASSERT( istr.eof() );
    901     CPPUNIT_ASSERT( val == 12345 );
    902     istr.clear();
    903 
    904     if (sizeof(short) == 2) {
    905       istr.str("177777");
    906       istr >> oct >> val;
    907       CPPUNIT_ASSERT( !istr.fail() );
    908       CPPUNIT_ASSERT( istr.eof() );
    909       CPPUNIT_ASSERT( val == -1 );
    910       istr.clear();
    911     }
    912   }
    913 
    914   //decimal input
    915   {
    916     istringstream istr;
    917     istr.str("10000");
    918     short val = -1;
    919     istr >> val;
    920     CPPUNIT_ASSERT( !istr.fail() );
    921     CPPUNIT_ASSERT( istr.eof() );
    922     CPPUNIT_ASSERT( val == 10000 );
    923     istr.clear();
    924 
    925     istr.str("+10000");
    926     val = -1;
    927     istr >> val;
    928     CPPUNIT_ASSERT( !istr.fail() );
    929     CPPUNIT_ASSERT( istr.eof() );
    930     CPPUNIT_ASSERT( val == 10000 );
    931     istr.clear();
    932 
    933     if (sizeof(short) == 2) {
    934       val = -1;
    935       istr.str("10000000");
    936       istr >> val;
    937       CPPUNIT_ASSERT( istr.fail() );
    938       CPPUNIT_ASSERT( istr.eof() );
    939       CPPUNIT_ASSERT( val == -1 );
    940       istr.clear();
    941     }
    942 
    943     val = -1;
    944     istr.str("0x0");
    945     istr >> val;
    946     CPPUNIT_ASSERT( !istr.fail() );
    947     CPPUNIT_ASSERT( !istr.eof() );
    948     CPPUNIT_ASSERT( val == 0 );
    949     istr.clear();
    950 
    951     val = -1;
    952     istr.str("000001");
    953     istr >> val;
    954     CPPUNIT_ASSERT( !istr.fail() );
    955     CPPUNIT_ASSERT( istr.eof() );
    956     CPPUNIT_ASSERT( val == 1 );
    957     istr.clear();
    958   }
    959 
    960   //hexadecimal input
    961   {
    962     istringstream istr;
    963     istr.str("3039");
    964     short val = -1;
    965     istr >> hex >> val;
    966     CPPUNIT_ASSERT( !istr.fail() );
    967     CPPUNIT_ASSERT( istr.eof() );
    968     CPPUNIT_ASSERT( val == 12345 );
    969     istr.clear();
    970 
    971     istr.str("x3039");
    972     val = -1;
    973     istr >> hex >> val;
    974     CPPUNIT_ASSERT( istr.fail() );
    975     CPPUNIT_ASSERT( !istr.eof() );
    976     CPPUNIT_ASSERT( val == -1 );
    977     istr.clear();
    978 
    979     istr.str("03039");
    980     val = -1;
    981     istr >> hex >> val;
    982     CPPUNIT_ASSERT( !istr.fail() );
    983     CPPUNIT_ASSERT( istr.eof() );
    984     CPPUNIT_ASSERT( val == 12345 );
    985     istr.clear();
    986 
    987     istr.str("0x3039");
    988     istr >> hex >> val;
    989     CPPUNIT_ASSERT( !istr.fail() );
    990     CPPUNIT_ASSERT( istr.eof() );
    991     CPPUNIT_ASSERT( val == 12345 );
    992     istr.clear();
    993 
    994     if (sizeof(short) == 2) {
    995       val = -1;
    996       istr.str("cfc7");
    997       istr >> hex >> val;
    998       CPPUNIT_ASSERT( !istr.fail() );
    999       CPPUNIT_ASSERT( istr.eof() );
   1000       CPPUNIT_ASSERT( val == -12345 );
   1001       istr.clear();
   1002     }
   1003   }
   1004 }
   1005 
   1006 void NumPutGetTest::inhex()
   1007 {
   1008   {
   1009     ostringstream s;
   1010     s << hex << 0;
   1011     CPPUNIT_CHECK( s.str() == "0" );
   1012   }
   1013   {
   1014     ostringstream s;
   1015     s << hex << 0xff;
   1016     CPPUNIT_CHECK( s.str() == "ff" );
   1017   }
   1018   {
   1019     ostringstream s;
   1020     s << hex << setw( 4 ) << 0xff;
   1021     CPPUNIT_CHECK( s.str() == "  ff" );
   1022   }
   1023   {
   1024     ostringstream s;
   1025     s << hex << setw( 4 ) << 0;
   1026     CPPUNIT_CHECK( s.str() == "   0" );
   1027   }
   1028   {
   1029     ostringstream s;
   1030     s << hex << showbase << 0;
   1031     CPPUNIT_CHECK( s.str() == "0" );
   1032   }
   1033   {
   1034     ostringstream s;
   1035     s << hex << showbase << 0xff;
   1036     CPPUNIT_CHECK( s.str() == "0xff" );
   1037   }
   1038   {
   1039     ostringstream s;
   1040     s << hex << showbase << setw( 4 ) << 0xff;
   1041     CPPUNIT_CHECK( s.str() == "0xff" );
   1042   }
   1043   { // special case for regression (partially duplicate CHECK_COMPLETE above):
   1044     ostringstream s;
   1045     s.setf( ios_base::internal, ios_base::adjustfield );
   1046     s << hex << showbase << setw(8+2) << 0;
   1047     CPPUNIT_CHECK( s.str() == "         0" );
   1048   }
   1049 }
   1050 
   1051 void NumPutGetTest::pointer()
   1052 {
   1053   // Problem with printing pointer to null
   1054 
   1055   /*
   1056    * Really C's formatting not help here, due to:
   1057    *
   1058    * p  The argument shall be a pointer to void. The value of
   1059    *    the pointer is converted to a sequence of printable characters,
   1060    *    in an implementation-defined manner.
   1061    */
   1062   {
   1063     /*
   1064     char buf[128];
   1065     void *p = (void *)0xff00;
   1066     sprintf( buf, "%p", p );
   1067     // cerr << buf << endl;
   1068     // Hmmm, I see 0xff00 on box with 32-bits address; pointer like 'unsigned hex'?
   1069     if ( sizeof( p ) == 2 ) {
   1070       CPPUNIT_ASSERT( strcmp( buf, "0xff00" ) == 0 );
   1071     } else if ( sizeof( p ) == 4 ) {
   1072       CPPUNIT_ASSERT( strcmp( buf, "0x0000ff00" ) == 0 );
   1073     } else if ( sizeof( p ) == 8 ) {
   1074       CPPUNIT_ASSERT( strcmp( buf, "0x000000000000ff00" ) == 0 );
   1075     } else {
   1076       CPPUNIT_CHECK( sizeof( p ) == 2 || sizeof( p ) == 4 || sizeof( p ) == 8 );
   1077     }
   1078     */
   1079   }
   1080   {
   1081     /*
   1082     char buf[128];
   1083     void *p = 0;
   1084     */
   1085     // sprintf( buf, "%p", p );
   1086     /* Cool. "%p" print '(nil)'; "%#x" print '0' */
   1087     // sprintf( buf, "%#x", (unsigned)p );
   1088     // cerr << buf << endl;
   1089   }
   1090   {
   1091     ostringstream s;
   1092     void *p = (void *)0xff00;
   1093     s << p;
   1094     CPPUNIT_ASSERT( s.good() );
   1095     if ( sizeof( p ) == 2 ) {
   1096       CPPUNIT_ASSERT( s.str() == "0xff00" );
   1097     } else if ( sizeof( p ) == 4 ) {
   1098       CPPUNIT_ASSERT( s.str() == "0x0000ff00" ); // this pass
   1099     } else if ( sizeof( p ) == 8 ) {
   1100       CPPUNIT_ASSERT( s.str() == "0x000000000000ff00" );
   1101     } else {
   1102       CPPUNIT_CHECK( sizeof( p ) == 2 || sizeof( p ) == 4 || sizeof( p ) == 8 );
   1103     }
   1104   }
   1105   {
   1106     ostringstream s;
   1107     void *p = 0;
   1108     s << p;
   1109     CPPUNIT_ASSERT( s.good() );
   1110     if ( sizeof( p ) == 2 ) {
   1111       CPPUNIT_ASSERT( s.str() == "0x0000" );
   1112     } else if ( sizeof( p ) == 4 ) {
   1113       CPPUNIT_ASSERT( s.str() == "0x00000000" ); // but this will fail, if follow %p
   1114     } else if ( sizeof( p ) == 8 ) {
   1115       CPPUNIT_ASSERT( s.str() == "0x0000000000000000" );
   1116     } else {
   1117       CPPUNIT_CHECK( sizeof( p ) == 2 || sizeof( p ) == 4 || sizeof( p ) == 8 );
   1118     }
   1119   }
   1120 }
   1121 
   1122 void NumPutGetTest::fix_float_long()
   1123 {
   1124   ostringstream str;
   1125 
   1126   str.setf(ios::fixed, ios::floatfield);
   1127   str << 1.0e+5;
   1128   CPPUNIT_CHECK( str.str() == "100000.000000" );
   1129 
   1130   reset_stream(str);
   1131   str.precision(0);
   1132   str << 1.0e+5;
   1133   CPPUNIT_CHECK( str.str() == "100000" );
   1134 
   1135   reset_stream(str);
   1136   str.precision(4);
   1137   str << 1.0e+5;
   1138   CPPUNIT_CHECK( str.str() == "100000.0000" );
   1139 
   1140   reset_stream(str);
   1141   str.precision(0);
   1142   str << 1.0e+83;
   1143   {
   1144     istringstream istr( str.str() );
   1145     double f;
   1146     istr >> f;
   1147     CPPUNIT_CHECK( !istr.fail() );
   1148     if ( int(numeric_limits<double>::digits10) < 83 ) {
   1149       double delta = 1.0;
   1150       for ( int ee = 83 - int(numeric_limits<double>::digits10); ee > 0; --ee ) {
   1151         delta *= 10.0;
   1152       }
   1153       // we may loss some digits here, but not more than mantissa:
   1154       CPPUNIT_CHECK( (f > (1.0e+83 - delta)) && (f < (1.0e+83 + delta)) );
   1155     } else {
   1156       CPPUNIT_CHECK( check_double(f, 1.0e+83) );
   1157     }
   1158   }
   1159 
   1160 #if 0 // #ifndef _STLP_NO_LONG_DOUBLE
   1161   reset_stream(str);
   1162   str.precision(0);
   1163   str << 1.0e+83l;
   1164   {
   1165     istringstream istr( str.str() );
   1166     long double f;
   1167     istr >> f;
   1168     CPPUNIT_CHECK( !istr.fail() );
   1169     if ( int(numeric_limits<long double>::digits10) < 83 ) {
   1170       long double delta = 1.0l;
   1171       for ( int ee = 83 - int(numeric_limits<long double>::digits10); ee > 0; --ee ) {
   1172         delta *= 10.0l;
   1173       }
   1174       // we may loss some digits here, but not more than mantissa:
   1175       cerr << "0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789" << endl;
   1176       cerr << str.str() << endl;
   1177       cerr << delta << endl;
   1178       cerr << f << endl;
   1179       CPPUNIT_CHECK( (f > (1.0e+83l - delta)) && (f < (1.0e+83l + delta)) );
   1180     } else {
   1181       CPPUNIT_CHECK( check_double(f, 1.0e+83l) );
   1182     }
   1183   }
   1184 #endif
   1185 
   1186   reset_stream(str);
   1187   str.precision(0);
   1188   str << numeric_limits<double>::max();
   1189   {
   1190     istringstream istr( str.str() );
   1191     double f;
   1192     istr >> f;
   1193     CPPUNIT_CHECK( !istr.fail() );
   1194     if ( int(numeric_limits<double>::digits10) < int(numeric_limits<double>::max_exponent10) ) {
   1195       double delta = 9.0;
   1196       for ( int ee = int(numeric_limits<double>::max_exponent10) - int(numeric_limits<double>::digits10); ee > 0; --ee ) {
   1197         delta *= 10.0;
   1198       }
   1199       // we may loss some digits here, but not more than mantissa:
   1200       CPPUNIT_CHECK( (f > (numeric_limits<double>::max() - delta)) );
   1201     }
   1202   }
   1203 
   1204 #if 0 // #ifndef _STLP_NO_LONG_DOUBLE
   1205   reset_stream(str);
   1206   str.precision(0);
   1207   str << numeric_limits<long double>::max();
   1208   {
   1209     istringstream istr( str.str() );
   1210     long double f;
   1211     istr >> f;
   1212     CPPUNIT_CHECK( !istr.fail() );
   1213     if ( int(numeric_limits<long double>::digits10) < int(numeric_limits<long double>::max_exponent10) ) {
   1214       long double delta = 1.0l;
   1215       for ( int ee = int(numeric_limits<long double>::max_exponent10) - int(numeric_limits<long double>::digits10); ee > 0; --ee ) {
   1216         delta *= 10.0l;
   1217       }
   1218       // we may loss some digits here, but not more than mantissa:
   1219       CPPUNIT_CHECK( (f > (numeric_limits<long double>::max() - delta)) );
   1220     }
   1221   }
   1222 #endif
   1223 }
   1224 
   1225 class CommaSepNumPunct : public numpunct<char> {
   1226   char do_thousands_sep() const { return ','; }
   1227   string do_grouping() const { return string("\1\2\3") + (char)CHAR_MAX; }
   1228 };
   1229 
   1230 #define CHECK2(val, expected) \
   1231   os.str(""); os << fixed << setprecision(3) << showpos << val; \
   1232   CPPUNIT_ASSERT( os.str() == expected )
   1233 
   1234 void NumPutGetTest::custom_numpunct()
   1235 {
   1236     ostringstream os;
   1237     locale loc(os.getloc(), new CommaSepNumPunct());
   1238     os.imbue(loc);
   1239 
   1240     CHECK2(1, "+1");
   1241     CHECK2(10, "+1,0");
   1242     CHECK2(100, "+10,0");
   1243     CHECK2(1000, "+1,00,0");
   1244 
   1245     CHECK2(1.234, "+1.234");
   1246     CHECK2(123.456, "+12,3.456");
   1247     CHECK2(1234.567, "+1,23,4.567");
   1248     CHECK2(12345.678, "+12,34,5.678");
   1249     CHECK2(123456.789, "+123,45,6.789");
   1250     CHECK2(1234567.891, "+1,234,56,7.891");
   1251     CHECK2(123456789.123, "+123,456,78,9.123");
   1252     //CHECK2(100000000000000000000000000000.0, "+100000000000000000000000,000,00,0.000");
   1253     CHECK2(numeric_limits<double>::infinity(), "+inf");
   1254 
   1255     CHECK2(-1.234, "-1.234");
   1256     CHECK2(-123.456, "-12,3.456");
   1257     CHECK2(-1234.567, "-1,23,4.567");
   1258     CHECK2(-12345.678, "-12,34,5.678");
   1259     CHECK2(-123456.789, "-123,45,6.789");
   1260     CHECK2(-1234567.891, "-1,234,56,7.891");
   1261     CHECK2(-123456789.123, "-123,456,78,9.123");
   1262     //CHECK2(-100000000000000000000000000000.0, "-100000000000000000000000,000,00,0.000");
   1263     CHECK2(-numeric_limits<double>::infinity(), "-inf");
   1264 }
   1265 
   1266 #endif
   1267