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 << "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.12345678f;
    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)
    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   {
    873     const char* p = "2.718281828459045235360287471352662497757247093e0";
    874     std::stringstream s;
    875     s << p;
    876     long double x;
    877     s >> x;
    878     CPPUNIT_ASSERT( x > 2.70l && x < 2.72l );
    879   }
    880 #endif
    881 }
    882 
    883 void NumPutGetTest::num_get_integer()
    884 {
    885   //octal input
    886   {
    887     istringstream istr;
    888     istr.str("30071");
    889     short val;
    890     istr >> oct >> val;
    891     CPPUNIT_ASSERT( !istr.fail() );
    892     CPPUNIT_ASSERT( istr.eof() );
    893     CPPUNIT_ASSERT( val == 12345 );
    894     istr.clear();
    895 
    896     if (sizeof(short) == 2) {
    897       istr.str("177777");
    898       istr >> oct >> val;
    899       CPPUNIT_ASSERT( !istr.fail() );
    900       CPPUNIT_ASSERT( istr.eof() );
    901       CPPUNIT_ASSERT( val == -1 );
    902       istr.clear();
    903     }
    904   }
    905 
    906   //decimal input
    907   {
    908     istringstream istr;
    909     istr.str("10000");
    910     short val = -1;
    911     istr >> val;
    912     CPPUNIT_ASSERT( !istr.fail() );
    913     CPPUNIT_ASSERT( istr.eof() );
    914     CPPUNIT_ASSERT( val == 10000 );
    915     istr.clear();
    916 
    917     istr.str("+10000");
    918     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     if (sizeof(short) == 2) {
    926       val = -1;
    927       istr.str("10000000");
    928       istr >> val;
    929       CPPUNIT_ASSERT( istr.fail() );
    930       CPPUNIT_ASSERT( istr.eof() );
    931       CPPUNIT_ASSERT( val == -1 );
    932       istr.clear();
    933     }
    934 
    935     val = -1;
    936     istr.str("0x0");
    937     istr >> val;
    938     CPPUNIT_ASSERT( !istr.fail() );
    939     CPPUNIT_ASSERT( !istr.eof() );
    940     CPPUNIT_ASSERT( val == 0 );
    941     istr.clear();
    942 
    943     val = -1;
    944     istr.str("000001");
    945     istr >> val;
    946     CPPUNIT_ASSERT( !istr.fail() );
    947     CPPUNIT_ASSERT( istr.eof() );
    948     CPPUNIT_ASSERT( val == 1 );
    949     istr.clear();
    950   }
    951 
    952   //hexadecimal input
    953   {
    954     istringstream istr;
    955     istr.str("3039");
    956     short val = -1;
    957     istr >> hex >> val;
    958     CPPUNIT_ASSERT( !istr.fail() );
    959     CPPUNIT_ASSERT( istr.eof() );
    960     CPPUNIT_ASSERT( val == 12345 );
    961     istr.clear();
    962 
    963     istr.str("x3039");
    964     val = -1;
    965     istr >> hex >> val;
    966     CPPUNIT_ASSERT( istr.fail() );
    967     CPPUNIT_ASSERT( !istr.eof() );
    968     CPPUNIT_ASSERT( val == -1 );
    969     istr.clear();
    970 
    971     istr.str("03039");
    972     val = -1;
    973     istr >> hex >> val;
    974     CPPUNIT_ASSERT( !istr.fail() );
    975     CPPUNIT_ASSERT( istr.eof() );
    976     CPPUNIT_ASSERT( val == 12345 );
    977     istr.clear();
    978 
    979     istr.str("0x3039");
    980     istr >> hex >> val;
    981     CPPUNIT_ASSERT( !istr.fail() );
    982     CPPUNIT_ASSERT( istr.eof() );
    983     CPPUNIT_ASSERT( val == 12345 );
    984     istr.clear();
    985 
    986     if (sizeof(short) == 2) {
    987       val = -1;
    988       istr.str("cfc7");
    989       istr >> hex >> val;
    990       CPPUNIT_ASSERT( !istr.fail() );
    991       CPPUNIT_ASSERT( istr.eof() );
    992       CPPUNIT_ASSERT( val == -12345 );
    993       istr.clear();
    994     }
    995   }
    996 }
    997 
    998 void NumPutGetTest::inhex()
    999 {
   1000   {
   1001     ostringstream s;
   1002     s << hex << 0;
   1003     CPPUNIT_CHECK( s.str() == "0" );
   1004   }
   1005   {
   1006     ostringstream s;
   1007     s << hex << 0xff;
   1008     CPPUNIT_CHECK( s.str() == "ff" );
   1009   }
   1010   {
   1011     ostringstream s;
   1012     s << hex << setw( 4 ) << 0xff;
   1013     CPPUNIT_CHECK( s.str() == "  ff" );
   1014   }
   1015   {
   1016     ostringstream s;
   1017     s << hex << setw( 4 ) << 0;
   1018     CPPUNIT_CHECK( s.str() == "   0" );
   1019   }
   1020   {
   1021     ostringstream s;
   1022     s << hex << showbase << 0;
   1023     CPPUNIT_CHECK( s.str() == "0" );
   1024   }
   1025   {
   1026     ostringstream s;
   1027     s << hex << showbase << 0xff;
   1028     CPPUNIT_CHECK( s.str() == "0xff" );
   1029   }
   1030   {
   1031     ostringstream s;
   1032     s << hex << showbase << setw( 4 ) << 0xff;
   1033     CPPUNIT_CHECK( s.str() == "0xff" );
   1034   }
   1035   { // special case for regression (partially duplicate CHECK_COMPLETE above):
   1036     ostringstream s;
   1037     s.setf( ios_base::internal, ios_base::adjustfield );
   1038     s << hex << showbase << setw(8+2) << 0;
   1039     CPPUNIT_CHECK( s.str() == "         0" );
   1040   }
   1041 }
   1042 
   1043 void NumPutGetTest::pointer()
   1044 {
   1045   // Problem with printing pointer to null
   1046 
   1047   /*
   1048    * Really C's formatting not help here, due to:
   1049    *
   1050    * p  The argument shall be a pointer to void. The value of
   1051    *    the pointer is converted to a sequence of printable characters,
   1052    *    in an implementation-defined manner.
   1053    */
   1054   {
   1055     /*
   1056     char buf[128];
   1057     void *p = (void *)0xff00;
   1058     sprintf( buf, "%p", p );
   1059     // cerr << buf << endl;
   1060     // Hmmm, I see 0xff00 on box with 32-bits address; pointer like 'unsigned hex'?
   1061     if ( sizeof( p ) == 2 ) {
   1062       CPPUNIT_ASSERT( strcmp( buf, "0xff00" ) == 0 );
   1063     } else if ( sizeof( p ) == 4 ) {
   1064       CPPUNIT_ASSERT( strcmp( buf, "0x0000ff00" ) == 0 );
   1065     } else if ( sizeof( p ) == 8 ) {
   1066       CPPUNIT_ASSERT( strcmp( buf, "0x000000000000ff00" ) == 0 );
   1067     } else {
   1068       CPPUNIT_CHECK( sizeof( p ) == 2 || sizeof( p ) == 4 || sizeof( p ) == 8 );
   1069     }
   1070     */
   1071   }
   1072   {
   1073     /*
   1074     char buf[128];
   1075     void *p = 0;
   1076     */
   1077     // sprintf( buf, "%p", p );
   1078     /* Cool. "%p" print '(nil)'; "%#x" print '0' */
   1079     // sprintf( buf, "%#x", (unsigned)p );
   1080     // cerr << buf << endl;
   1081   }
   1082   {
   1083     ostringstream s;
   1084     void *p = (void *)0xff00;
   1085     s << p;
   1086     CPPUNIT_ASSERT( s.good() );
   1087     if ( sizeof( p ) == 2 ) {
   1088       CPPUNIT_ASSERT( s.str() == "0xff00" );
   1089     } else if ( sizeof( p ) == 4 ) {
   1090       CPPUNIT_ASSERT( s.str() == "0x0000ff00" ); // this pass
   1091     } else if ( sizeof( p ) == 8 ) {
   1092       CPPUNIT_ASSERT( s.str() == "0x000000000000ff00" );
   1093     } else {
   1094       CPPUNIT_CHECK( sizeof( p ) == 2 || sizeof( p ) == 4 || sizeof( p ) == 8 );
   1095     }
   1096   }
   1097   {
   1098     ostringstream s;
   1099     void *p = 0;
   1100     s << p;
   1101     CPPUNIT_ASSERT( s.good() );
   1102     if ( sizeof( p ) == 2 ) {
   1103       CPPUNIT_ASSERT( s.str() == "0x0000" );
   1104     } else if ( sizeof( p ) == 4 ) {
   1105       CPPUNIT_ASSERT( s.str() == "0x00000000" ); // but this will fail, if follow %p
   1106     } else if ( sizeof( p ) == 8 ) {
   1107       CPPUNIT_ASSERT( s.str() == "0x0000000000000000" );
   1108     } else {
   1109       CPPUNIT_CHECK( sizeof( p ) == 2 || sizeof( p ) == 4 || sizeof( p ) == 8 );
   1110     }
   1111   }
   1112 }
   1113 
   1114 void NumPutGetTest::fix_float_long()
   1115 {
   1116   ostringstream str;
   1117 
   1118   str.setf(ios::fixed, ios::floatfield);
   1119   str << 1.0e+5;
   1120   CPPUNIT_CHECK( str.str() == "100000.000000" );
   1121 
   1122   reset_stream(str);
   1123   str.precision(0);
   1124   str << 1.0e+5;
   1125   CPPUNIT_CHECK( str.str() == "100000" );
   1126 
   1127   reset_stream(str);
   1128   str.precision(4);
   1129   str << 1.0e+5;
   1130   CPPUNIT_CHECK( str.str() == "100000.0000" );
   1131 
   1132   reset_stream(str);
   1133   str.precision(0);
   1134   str << 1.0e+83;
   1135   {
   1136     istringstream istr( str.str() );
   1137     double f;
   1138     istr >> f;
   1139     CPPUNIT_CHECK( !istr.fail() );
   1140     if ( int(numeric_limits<double>::digits10) < 83 ) {
   1141       double delta = 1.0;
   1142       for ( int ee = 83 - int(numeric_limits<double>::digits10); ee > 0; --ee ) {
   1143         delta *= 10.0;
   1144       }
   1145       // we may loss some digits here, but not more than mantissa:
   1146       CPPUNIT_CHECK( (f > (1.0e+83 - delta)) && (f < (1.0e+83 + delta)) );
   1147     } else {
   1148       CPPUNIT_CHECK( check_double(f, 1.0e+83) );
   1149     }
   1150   }
   1151 
   1152 #if 0 // #ifndef _STLP_NO_LONG_DOUBLE
   1153   reset_stream(str);
   1154   str.precision(0);
   1155   str << 1.0e+83l;
   1156   {
   1157     istringstream istr( str.str() );
   1158     long double f;
   1159     istr >> f;
   1160     CPPUNIT_CHECK( !istr.fail() );
   1161     if ( int(numeric_limits<long double>::digits10) < 83 ) {
   1162       long double delta = 1.0l;
   1163       for ( int ee = 83 - int(numeric_limits<long double>::digits10); ee > 0; --ee ) {
   1164         delta *= 10.0l;
   1165       }
   1166       // we may loss some digits here, but not more than mantissa:
   1167       cerr << "0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789" << endl;
   1168       cerr << str.str() << endl;
   1169       cerr << delta << endl;
   1170       cerr << f << endl;
   1171       CPPUNIT_CHECK( (f > (1.0e+83l - delta)) && (f < (1.0e+83l + delta)) );
   1172     } else {
   1173       CPPUNIT_CHECK( check_double(f, 1.0e+83l) );
   1174     }
   1175   }
   1176 #endif
   1177 
   1178   reset_stream(str);
   1179   str.precision(0);
   1180   str << numeric_limits<double>::max();
   1181   {
   1182     istringstream istr( str.str() );
   1183     double f;
   1184     istr >> f;
   1185     CPPUNIT_CHECK( !istr.fail() );
   1186     if ( int(numeric_limits<double>::digits10) < int(numeric_limits<double>::max_exponent10) ) {
   1187       double delta = 9.0;
   1188       for ( int ee = int(numeric_limits<double>::max_exponent10) - int(numeric_limits<double>::digits10); ee > 0; --ee ) {
   1189         delta *= 10.0;
   1190       }
   1191       // we may loss some digits here, but not more than mantissa:
   1192       CPPUNIT_CHECK( (f > (numeric_limits<double>::max() - delta)) );
   1193     }
   1194   }
   1195 
   1196 #if 0 // #ifndef _STLP_NO_LONG_DOUBLE
   1197   reset_stream(str);
   1198   str.precision(0);
   1199   str << numeric_limits<long double>::max();
   1200   {
   1201     istringstream istr( str.str() );
   1202     long double f;
   1203     istr >> f;
   1204     CPPUNIT_CHECK( !istr.fail() );
   1205     if ( int(numeric_limits<long double>::digits10) < int(numeric_limits<long double>::max_exponent10) ) {
   1206       long double delta = 1.0l;
   1207       for ( int ee = int(numeric_limits<long double>::max_exponent10) - int(numeric_limits<long double>::digits10); ee > 0; --ee ) {
   1208         delta *= 10.0l;
   1209       }
   1210       // we may loss some digits here, but not more than mantissa:
   1211       CPPUNIT_CHECK( (f > (numeric_limits<long double>::max() - delta)) );
   1212     }
   1213   }
   1214 #endif
   1215 }
   1216 
   1217 class CommaSepNumPunct : public numpunct<char> {
   1218   char do_thousands_sep() const { return ','; }
   1219   string do_grouping() const { return string("\1\2\3") + (char)CHAR_MAX; }
   1220 };
   1221 
   1222 #define CHECK2(val, expected) \
   1223   os.str(""); os << fixed << setprecision(3) << showpos << val; \
   1224   CPPUNIT_ASSERT( os.str() == expected )
   1225 
   1226 void NumPutGetTest::custom_numpunct()
   1227 {
   1228     ostringstream os;
   1229     locale loc(os.getloc(), new CommaSepNumPunct());
   1230     os.imbue(loc);
   1231 
   1232     CHECK2(1, "+1");
   1233     CHECK2(10, "+1,0");
   1234     CHECK2(100, "+10,0");
   1235     CHECK2(1000, "+1,00,0");
   1236 
   1237     CHECK2(1.234, "+1.234");
   1238     CHECK2(123.456, "+12,3.456");
   1239     CHECK2(1234.567, "+1,23,4.567");
   1240     CHECK2(12345.678, "+12,34,5.678");
   1241     CHECK2(123456.789, "+123,45,6.789");
   1242     CHECK2(1234567.891, "+1,234,56,7.891");
   1243     CHECK2(123456789.123, "+123,456,78,9.123");
   1244     //CHECK2(100000000000000000000000000000.0, "+100000000000000000000000,000,00,0.000");
   1245     CHECK2(numeric_limits<double>::infinity(), "+inf");
   1246 
   1247     CHECK2(-1.234, "-1.234");
   1248     CHECK2(-123.456, "-12,3.456");
   1249     CHECK2(-1234.567, "-1,23,4.567");
   1250     CHECK2(-12345.678, "-12,34,5.678");
   1251     CHECK2(-123456.789, "-123,45,6.789");
   1252     CHECK2(-1234567.891, "-1,234,56,7.891");
   1253     CHECK2(-123456789.123, "-123,456,78,9.123");
   1254     //CHECK2(-100000000000000000000000000000.0, "-100000000000000000000000,000,00,0.000");
   1255     CHECK2(-numeric_limits<double>::infinity(), "-inf");
   1256 }
   1257 
   1258 #endif
   1259