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