FSF GCC merge 02/23/03
[official-gcc.git] / libstdc++-v3 / testsuite / 27_io / ostream_inserter_arith.cc
blobe4e618d68d86b84bc49966f4f3adb76d11092367
1 // 1999-11-15 Kevin Ediger <kediger@licor.com>
2 // test the floating point inserters (facet num_put)
4 // Copyright (C) 1999, 2002 Free Software Foundation, Inc.
5 //
6 // This file is part of the GNU ISO C++ Library. This library is free
7 // software; you can redistribute it and/or modify it under the
8 // terms of the GNU General Public License as published by the
9 // Free Software Foundation; either version 2, or (at your option)
10 // any later version.
12 // This library is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU General Public License for more details.
17 // You should have received a copy of the GNU General Public License along
18 // with this library; see the file COPYING. If not, write to the Free
19 // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
20 // USA.
22 #include <cstdio> // for sprintf
23 #include <cmath> // for abs
24 #include <cfloat> // for DBL_EPSILON
25 #include <iostream>
26 #include <iomanip>
27 #include <locale>
28 #include <sstream>
29 #include <limits>
30 #include <testsuite_hooks.h>
32 using namespace std;
34 #ifndef DEBUG_ASSERT
35 # define TEST_NUMPUT_VERBOSE 1
36 #endif
38 struct _TestCase
40 double val;
42 int precision;
43 int width;
44 char decimal;
45 char fill;
47 bool fixed;
48 bool scientific;
49 bool showpos;
50 bool showpoint;
51 bool uppercase;
52 bool internal;
53 bool left;
54 bool right;
56 const char* result;
57 #if _GLIBCPP_USE_WCHAR_T
58 const wchar_t* wresult;
59 #endif
62 static bool T=true;
63 static bool F=false;
65 static _TestCase testcases[] =
67 #if _GLIBCPP_USE_WCHAR_T
68 // standard output (no formatting applied) 1-4
69 { 1.2, 6,0,'.',' ', F,F,F,F,F,F,F,F, "1.2",L"1.2" },
70 { 54, 6,0,'.',' ', F,F,F,F,F,F,F,F, "54",L"54" },
71 { -.012, 6,0,'.',' ', F,F,F,F,F,F,F,F, "-0.012",L"-0.012" },
72 { -.00000012, 6,0,'.',' ', F,F,F,F,F,F,F,F, "-1.2e-07",L"-1.2e-07" },
74 // fixed formatting 5-11
75 { 10.2345, 0,0,'.',' ', T,F,F,F,F,F,F,F, "10",L"10" },
76 { 10.2345, 0,0,'.',' ', T,F,F,T,F,F,F,F, "10.",L"10." },
77 { 10.2345, 1,0,'.',' ', T,F,F,F,F,F,F,F, "10.2",L"10.2" },
78 { 10.2345, 4,0,'.',' ', T,F,F,F,F,F,F,F, "10.2345",L"10.2345" },
79 { 10.2345, 6,0,'.',' ', T,F,T,F,F,F,F,F, "+10.234500",L"+10.234500" },
80 { -10.2345, 6,0,'.',' ', T,F,F,F,F,F,F,F, "-10.234500",L"-10.234500" },
81 { -10.2345, 6,0,',',' ', T,F,F,F,F,F,F,F, "-10,234500",L"-10,234500" },
83 // fixed formatting with width 12-22
84 { 10.2345, 4,5,'.',' ', T,F,F,F,F,F,F,F, "10.2345",L"10.2345" },
85 { 10.2345, 4,6,'.',' ', T,F,F,F,F,F,F,F, "10.2345",L"10.2345" },
86 { 10.2345, 4,7,'.',' ', T,F,F,F,F,F,F,F, "10.2345",L"10.2345" },
87 { 10.2345, 4,8,'.',' ', T,F,F,F,F,F,F,F, " 10.2345",L" 10.2345" },
88 { 10.2345, 4,10,'.',' ', T,F,F,F,F,F,F,F, " 10.2345",L" 10.2345" },
89 { 10.2345, 4,10,'.',' ', T,F,F,F,F,F,T,F, "10.2345 ",L"10.2345 " },
90 { 10.2345, 4,10,'.',' ', T,F,F,F,F,F,F,T, " 10.2345",L" 10.2345" },
91 { 10.2345, 4,10,'.',' ', T,F,F,F,F,T,F,F, " 10.2345",L" 10.2345" },
92 { -10.2345, 4,10,'.',' ', T,F,F,F,F,T,F,F, "- 10.2345",L"- 10.2345" },
93 { -10.2345, 4,10,'.','A', T,F,F,F,F,T,F,F, "-AA10.2345",L"-AA10.2345" },
94 { 10.2345, 4,10,'.','#', T,F,T,F,F,T,F,F, "+##10.2345",L"+##10.2345" },
96 // scientific formatting 23-29
97 { 1.23e+12, 1,0,'.',' ', F,T,F,F,F,F,F,F, "1.2e+12",L"1.2e+12" },
98 { 1.23e+12, 1,0,'.',' ', F,T,F,F,T,F,F,F, "1.2E+12",L"1.2E+12" },
99 { 1.23e+12, 2,0,'.',' ', F,T,F,F,F,F,F,F, "1.23e+12",L"1.23e+12" },
100 { 1.23e+12, 3,0,'.',' ', F,T,F,F,F,F,F,F, "1.230e+12",L"1.230e+12" },
101 { 1.23e+12, 3,0,'.',' ', F,T,T,F,F,F,F,F, "+1.230e+12",L"+1.230e+12" },
102 { -1.23e-12, 3,0,'.',' ', F,T,F,F,F,F,F,F, "-1.230e-12",L"-1.230e-12" },
103 { 1.23e+12, 3,0,',',' ', F,T,F,F,F,F,F,F, "1,230e+12",L"1,230e+12" },
104 #else
105 // standard output (no formatting applied)
106 { 1.2, 6,0,'.',' ', F,F,F,F,F,F,F,F, "1.2" },
107 { 54, 6,0,'.',' ', F,F,F,F,F,F,F,F, "54" },
108 { -.012, 6,0,'.',' ', F,F,F,F,F,F,F,F, "-0.012" },
109 { -.00000012, 6,0,'.',' ', F,F,F,F,F,F,F,F, "-1.2e-07" },
111 // fixed formatting
112 { 10.2345, 0,0,'.',' ', T,F,F,F,F,F,F,F, "10" },
113 { 10.2345, 0,0,'.',' ', T,F,F,T,F,F,F,F, "10." },
114 { 10.2345, 1,0,'.',' ', T,F,F,F,F,F,F,F, "10.2" },
115 { 10.2345, 4,0,'.',' ', T,F,F,F,F,F,F,F, "10.2345" },
116 { 10.2345, 6,0,'.',' ', T,F,T,F,F,F,F,F, "+10.234500" },
117 { -10.2345, 6,0,'.',' ', T,F,F,F,F,F,F,F, "-10.234500" },
118 { -10.2345, 6,0,',',' ', T,F,F,F,F,F,F,F, "-10,234500" },
120 // fixed formatting with width
121 { 10.2345, 4,5,'.',' ', T,F,F,F,F,F,F,F, "10.2345" },
122 { 10.2345, 4,6,'.',' ', T,F,F,F,F,F,F,F, "10.2345" },
123 { 10.2345, 4,7,'.',' ', T,F,F,F,F,F,F,F, "10.2345" },
124 { 10.2345, 4,8,'.',' ', T,F,F,F,F,F,F,F, " 10.2345" },
125 { 10.2345, 4,10,'.',' ', T,F,F,F,F,F,F,F, " 10.2345" },
126 { 10.2345, 4,10,'.',' ', T,F,F,F,F,F,T,F, "10.2345 " },
127 { 10.2345, 4,10,'.',' ', T,F,F,F,F,F,F,T, " 10.2345" },
128 { 10.2345, 4,10,'.',' ', T,F,F,F,F,T,F,F, " 10.2345" },
129 { -10.2345, 4,10,'.',' ', T,F,F,F,F,T,F,F, "- 10.2345" },
130 { -10.2345, 4,10,'.','A', T,F,F,F,F,T,F,F, "-AA10.2345" },
131 { 10.2345, 4,10,'.','#', T,F,T,F,F,T,F,F, "+##10.2345" },
133 // scientific formatting
134 { 1.23e+12, 1,0,'.',' ', F,T,F,F,F,F,F,F, "1.2e+12" },
135 { 1.23e+12, 1,0,'.',' ', F,T,F,F,T,F,F,F, "1.2E+12" },
136 { 1.23e+12, 2,0,'.',' ', F,T,F,F,F,F,F,F, "1.23e+12" },
137 { 1.23e+12, 3,0,'.',' ', F,T,F,F,F,F,F,F, "1.230e+12" },
138 { 1.23e+12, 3,0,'.',' ', F,T,T,F,F,F,F,F, "+1.230e+12" },
139 { -1.23e-12, 3,0,'.',' ', F,T,F,F,F,F,F,F, "-1.230e-12" },
140 { 1.23e+12, 3,0,',',' ', F,T,F,F,F,F,F,F, "1,230e+12" },
141 #endif
144 template<typename _CharT>
145 class testpunct : public numpunct<_CharT>
147 public:
148 typedef _CharT char_type;
149 const char_type dchar;
151 explicit
152 testpunct(char_type decimal_char) : numpunct<_CharT>(), dchar(decimal_char)
155 protected:
156 char_type
157 do_decimal_point() const
158 { return dchar; }
160 char_type
161 do_thousands_sep() const
162 { return ','; }
164 string
165 do_grouping() const
166 { return string(); }
169 template<typename _CharT>
170 void apply_formatting(const _TestCase & tc, basic_ostream<_CharT> & os)
172 os.precision(tc.precision);
173 os.width(tc.width);
174 os.fill(static_cast<_CharT>(tc.fill));
175 if (tc.fixed)
176 os.setf(ios::fixed);
177 if (tc.scientific)
178 os.setf(ios::scientific);
179 if (tc.showpos)
180 os.setf(ios::showpos);
181 if (tc.showpoint)
182 os.setf(ios::showpoint);
183 if (tc.uppercase)
184 os.setf(ios::uppercase);
185 if (tc.internal)
186 os.setf(ios::internal);
187 if (tc.left)
188 os.setf(ios::left);
189 if (tc.right)
190 os.setf(ios::right);
194 test01()
196 bool test = true;
197 for (int j=0; j<sizeof(testcases)/sizeof(testcases[0]); j++)
199 _TestCase & tc = testcases[j];
200 #ifdef TEST_NUMPUT_VERBOSE
201 cout << "expect: " << tc.result << endl;
202 #endif
203 // test double with char type
205 testpunct<char>* __tp = new testpunct<char>(tc.decimal);
206 ostringstream os;
207 locale __loc(os.getloc(), __tp);
208 os.imbue(__loc);
209 apply_formatting(tc, os);
210 os << tc.val;
211 #ifdef TEST_NUMPUT_VERBOSE
212 cout << j << "result 1: " << os.str() << endl;
213 #endif
214 VERIFY( os && os.str() == tc.result );
216 // test long double with char type
218 testpunct<char>* __tp = new testpunct<char>(tc.decimal);
219 ostringstream os;
220 locale __loc(os.getloc(), __tp);
221 os.imbue(__loc);
222 apply_formatting(tc, os);
223 os << (long double)tc.val;
224 #ifdef TEST_NUMPUT_VERBOSE
225 cout << j << "result 2: " << os.str() << endl;
226 #endif
227 VERIFY( os && os.str() == tc.result );
229 #if _GLIBCPP_USE_WCHAR_T
230 // test double with wchar_t type
232 testpunct<wchar_t>* __tp = new testpunct<wchar_t>(tc.decimal);
233 wostringstream os;
234 locale __loc(os.getloc(), __tp);
235 os.imbue(__loc);
236 apply_formatting(tc, os);
237 os << tc.val;
238 VERIFY( os && os.str() == tc.wresult );
240 // test long double with wchar_t type
242 testpunct<wchar_t>* __tp = new testpunct<wchar_t>(tc.decimal);
243 wostringstream os;
244 locale __loc(os.getloc(), __tp);
245 os.imbue(__loc);
246 apply_formatting(tc, os);
247 os << (long double)tc.val;
248 VERIFY( os && os.str() == tc.wresult );
250 #endif
253 return 0;
257 test02()
259 bool test = true;
260 // make sure we can output a very long float
261 long double val = 1.2345678901234567890123456789e+1000L;
262 int prec = numeric_limits<long double>::digits10;
264 ostringstream os;
265 os.precision(prec);
266 os.setf(ios::scientific);
267 os << val;
269 char largebuf[512];
270 sprintf(largebuf, "%.*Le", prec, val);
271 #ifdef TEST_NUMPUT_VERBOSE
272 cout << "expect: " << largebuf << endl;
273 cout << "result: " << os.str() << endl;
274 #endif
275 VERIFY(os && os.str() == largebuf);
277 // Make sure we can output a long float in fixed format
278 // without seg-faulting (libstdc++/4402)
279 double val2 = 3.5e230;
281 ostringstream os2;
282 os2.precision(3);
283 os2.setf(ios::fixed);
284 os2 << val2;
286 sprintf(largebuf, "%.*f", 3, val2);
287 #ifdef TEST_NUMPUT_VERBOSE
288 cout << "expect: " << largebuf << endl;
289 cout << "result: " << os2.str() << endl;
290 #endif
291 VERIFY(os2 && os2.str() == largebuf);
293 // Check it can be done in a locale with grouping on.
294 locale loc2("de_DE");
295 os2.imbue(loc2);
296 os2 << fixed << setprecision(3) << val2 << endl;
297 os2 << endl;
298 os2 << fixed << setprecision(1) << val2 << endl;
300 return 0;
303 template<typename T>
304 bool
305 test03_check(T n)
307 stringbuf strbuf;
308 ostream o(&strbuf);
309 const char *expect;
310 bool test = true;
312 if (numeric_limits<T>::digits + 1 == 16)
313 expect = "177777 ffff";
314 else if (numeric_limits<T>::digits + 1 == 32)
315 expect = "37777777777 ffffffff";
316 else if (numeric_limits<T>::digits + 1 == 64)
317 expect = "1777777777777777777777 ffffffffffffffff";
318 else
319 expect = "wow, you've got some big numbers here";
321 o << oct << n << ' ' << hex << n;
322 VERIFY ( strbuf.str() == expect );
324 return test;
327 int
328 test03()
330 short s = -1;
331 int i = -1;
332 long l = -1;
333 bool test = true;
335 test &= test03_check (s);
336 test &= test03_check (i);
337 test &= test03_check (l);
339 return 0;
342 // libstdc++/3655
344 test04()
346 stringbuf strbuf1, strbuf2;
347 ostream o1(&strbuf1), o2(&strbuf2);
348 bool test = true;
350 o1 << hex << showbase << setw(6) << internal << 0xff;
351 VERIFY( strbuf1.str() == "0x ff" );
353 // ... vs internal-adjusted const char*-type objects
354 o2 << hex << showbase << setw(6) << internal << "0xff";
355 VERIFY( strbuf2.str() == " 0xff" );
357 return 0;
361 test05()
363 double pi = 3.14159265358979323846;
364 ostringstream ostr;
365 ostr.precision(20);
366 ostr << pi;
367 string sval = ostr.str();
368 istringstream istr (sval);
369 double d;
370 istr >> d;
371 VERIFY( abs(pi-d)/pi < DBL_EPSILON );
372 return 0;
376 // libstdc++/9151
378 test06()
380 int prec = numeric_limits<double>::digits10 + 2;
381 double oval = numeric_limits<double>::min();
383 stringstream ostr;
384 ostr.precision(prec);
385 ostr << oval;
386 string sval = ostr.str();
387 istringstream istr (sval);
388 double ival;
389 istr >> ival;
390 VERIFY( abs(oval-ival)/oval < DBL_EPSILON );
391 return 0;
394 int
395 main()
397 test01();
398 test02();
399 test03();
400 test04();
401 test05();
402 test06();
403 #ifdef TEST_NUMPUT_VERBOSE
404 cout << "Test passed!" << endl;
405 #endif
406 return 0;