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