t-istream.cc revision 1.1.1.1.2.1 1 1.1 mrg /* Test istream formatted input.
2 1.1 mrg
3 1.1 mrg Copyright 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
4 1.1 mrg
5 1.1.1.1.2.1 yamt This file is part of the GNU MP Library test suite.
6 1.1 mrg
7 1.1.1.1.2.1 yamt The GNU MP Library test suite is free software; you can redistribute it
8 1.1.1.1.2.1 yamt and/or modify it under the terms of the GNU General Public License as
9 1.1.1.1.2.1 yamt published by the Free Software Foundation; either version 3 of the License,
10 1.1.1.1.2.1 yamt or (at your option) any later version.
11 1.1.1.1.2.1 yamt
12 1.1.1.1.2.1 yamt The GNU MP Library test suite is distributed in the hope that it will be
13 1.1.1.1.2.1 yamt useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
14 1.1.1.1.2.1 yamt MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
15 1.1.1.1.2.1 yamt Public License for more details.
16 1.1 mrg
17 1.1.1.1.2.1 yamt You should have received a copy of the GNU General Public License along with
18 1.1.1.1.2.1 yamt the GNU MP Library test suite. If not, see http://www.gnu.org/licenses/. */
19 1.1 mrg
20 1.1 mrg #include <iostream>
21 1.1 mrg #include <cstdlib>
22 1.1 mrg #include <cstring>
23 1.1 mrg
24 1.1 mrg #include "gmp.h"
25 1.1 mrg #include "gmp-impl.h"
26 1.1 mrg #include "tests.h"
27 1.1 mrg
28 1.1 mrg using namespace std;
29 1.1 mrg
30 1.1 mrg
31 1.1 mrg // Under option_check_standard, the various test cases for mpz operator>>
32 1.1 mrg // are put through the standard operator>> for long, and likewise mpf
33 1.1 mrg // operator>> is put through double.
34 1.1 mrg //
35 1.1 mrg // In g++ 3.3 this results in some printouts about the final position
36 1.1 mrg // indicated for something like ".e123". Our mpf code stops at the "e"
37 1.1 mrg // since there's no mantissa digits, but g++ reads the whole thing and only
38 1.1 mrg // then decides it's bad.
39 1.1 mrg
40 1.1.1.1.2.1 yamt bool option_check_standard = false;
41 1.1 mrg
42 1.1 mrg
43 1.1 mrg // On some versions of g++ 2.96 it's been observed that putback() may leave
44 1.1 mrg // tellg() unchanged. We believe this is incorrect and presumably the
45 1.1 mrg // result of a bug, since for instance it's ok in g++ 2.95 and g++ 3.3. We
46 1.1 mrg // detect the problem at runtime and disable affected checks.
47 1.1 mrg
48 1.1.1.1.2.1 yamt bool putback_tellg_works = true;
49 1.1 mrg
50 1.1 mrg void
51 1.1 mrg check_putback_tellg (void)
52 1.1 mrg {
53 1.1 mrg istringstream input ("hello");
54 1.1 mrg streampos old_pos, new_pos;
55 1.1 mrg char c;
56 1.1 mrg
57 1.1 mrg input.get(c);
58 1.1 mrg old_pos = input.tellg();
59 1.1 mrg input.putback(c);
60 1.1 mrg new_pos = input.tellg();
61 1.1 mrg
62 1.1 mrg if (old_pos == new_pos)
63 1.1 mrg {
64 1.1 mrg cout << "Warning, istringstream has a bug: putback() doesn't update tellg().\n";;
65 1.1 mrg cout << "Tests on tellg() will be skipped.\n";
66 1.1.1.1.2.1 yamt putback_tellg_works = false;
67 1.1 mrg }
68 1.1 mrg }
69 1.1 mrg
70 1.1 mrg
71 1.1 mrg #define WRONG(str) \
72 1.1 mrg do { \
73 1.1 mrg cout << str ", data[" << i << "]\n"; \
74 1.1 mrg cout << " input: \"" << data[i].input << "\"\n"; \
75 1.1 mrg cout << " flags: " << hex << input.flags() << dec << "\n"; \
76 1.1 mrg } while (0)
77 1.1 mrg
78 1.1 mrg void
79 1.1 mrg check_mpz (void)
80 1.1 mrg {
81 1.1 mrg static const struct {
82 1.1 mrg const char *input;
83 1.1 mrg int want_pos;
84 1.1 mrg const char *want;
85 1.1 mrg ios::fmtflags flags;
86 1.1 mrg
87 1.1 mrg } data[] = {
88 1.1 mrg
89 1.1 mrg { "0", -1, "0", (ios::fmtflags) 0 },
90 1.1 mrg { "123", -1, "123", (ios::fmtflags) 0 },
91 1.1 mrg { "0123", -1, "83", (ios::fmtflags) 0 },
92 1.1 mrg { "0x123", -1, "291", (ios::fmtflags) 0 },
93 1.1 mrg { "-123", -1, "-123", (ios::fmtflags) 0 },
94 1.1 mrg { "-0123", -1, "-83", (ios::fmtflags) 0 },
95 1.1 mrg { "-0x123", -1, "-291", (ios::fmtflags) 0 },
96 1.1 mrg { "+123", -1, "123", (ios::fmtflags) 0 },
97 1.1 mrg { "+0123", -1, "83", (ios::fmtflags) 0 },
98 1.1 mrg { "+0x123", -1, "291", (ios::fmtflags) 0 },
99 1.1 mrg
100 1.1 mrg { "0", -1, "0", ios::dec },
101 1.1 mrg { "1f", 1, "1", ios::dec },
102 1.1 mrg { "011f", 3, "11", ios::dec },
103 1.1 mrg { "123", -1, "123", ios::dec },
104 1.1 mrg { "-1f", 2, "-1", ios::dec },
105 1.1 mrg { "-011f", 4, "-11", ios::dec },
106 1.1 mrg { "-123", -1, "-123", ios::dec },
107 1.1 mrg { "+1f", 2, "1", ios::dec },
108 1.1 mrg { "+011f", 4, "11", ios::dec },
109 1.1 mrg { "+123", -1, "123", ios::dec },
110 1.1 mrg
111 1.1 mrg { "0", -1, "0", ios::oct },
112 1.1 mrg { "123", -1, "83", ios::oct },
113 1.1 mrg { "-123", -1, "-83", ios::oct },
114 1.1 mrg { "+123", -1, "83", ios::oct },
115 1.1 mrg
116 1.1 mrg { "0", -1, "0", ios::hex },
117 1.1 mrg { "123", -1, "291", ios::hex },
118 1.1 mrg { "ff", -1, "255", ios::hex },
119 1.1 mrg { "FF", -1, "255", ios::hex },
120 1.1 mrg { "-123", -1, "-291", ios::hex },
121 1.1 mrg { "-ff", -1, "-255", ios::hex },
122 1.1 mrg { "-FF", -1, "-255", ios::hex },
123 1.1 mrg { "+123", -1, "291", ios::hex },
124 1.1 mrg { "+ff", -1, "255", ios::hex },
125 1.1 mrg { "+FF", -1, "255", ios::hex },
126 1.1 mrg { "ab", -1, "171", ios::hex },
127 1.1 mrg { "cd", -1, "205", ios::hex },
128 1.1 mrg { "ef", -1, "239", ios::hex },
129 1.1 mrg
130 1.1 mrg { " 123", 0, NULL, (ios::fmtflags) 0 }, // not without skipws
131 1.1 mrg { " 123", -1, "123", ios::skipws },
132 1.1 mrg };
133 1.1 mrg
134 1.1 mrg mpz_t got, want;
135 1.1.1.1.2.1 yamt bool got_ok, want_ok;
136 1.1.1.1.2.1 yamt bool got_eof, want_eof;
137 1.1 mrg long got_si, want_si;
138 1.1 mrg streampos init_tellg, got_pos, want_pos;
139 1.1 mrg
140 1.1 mrg mpz_init (got);
141 1.1 mrg mpz_init (want);
142 1.1 mrg
143 1.1 mrg for (size_t i = 0; i < numberof (data); i++)
144 1.1 mrg {
145 1.1.1.1.2.1 yamt size_t input_length = strlen (data[i].input);
146 1.1 mrg want_pos = (data[i].want_pos == -1
147 1.1.1.1.2.1 yamt ? input_length : data[i].want_pos);
148 1.1.1.1.2.1 yamt want_eof = (want_pos == streampos(input_length));
149 1.1 mrg
150 1.1 mrg want_ok = (data[i].want != NULL);
151 1.1 mrg
152 1.1 mrg if (data[i].want != NULL)
153 1.1 mrg mpz_set_str_or_abort (want, data[i].want, 0);
154 1.1 mrg else
155 1.1 mrg mpz_set_ui (want, 0L);
156 1.1 mrg
157 1.1 mrg if (option_check_standard && mpz_fits_slong_p (want))
158 1.1 mrg {
159 1.1 mrg istringstream input (data[i].input);
160 1.1 mrg input.flags (data[i].flags);
161 1.1 mrg init_tellg = input.tellg();
162 1.1 mrg want_si = mpz_get_si (want);
163 1.1 mrg
164 1.1 mrg input >> got_si;
165 1.1.1.1.2.1 yamt got_ok = !input.fail();
166 1.1.1.1.2.1 yamt got_eof = input.eof();
167 1.1 mrg input.clear();
168 1.1 mrg got_pos = input.tellg() - init_tellg;
169 1.1 mrg
170 1.1 mrg if (got_ok != want_ok)
171 1.1 mrg {
172 1.1 mrg WRONG ("stdc++ operator>> wrong status, check_mpz");
173 1.1 mrg cout << " want_ok: " << want_ok << "\n";
174 1.1 mrg cout << " got_ok: " << got_ok << "\n";
175 1.1 mrg }
176 1.1 mrg if (want_ok && got_si != want_si)
177 1.1 mrg {
178 1.1 mrg WRONG ("stdc++ operator>> wrong result, check_mpz");
179 1.1 mrg cout << " got_si: " << got_si << "\n";
180 1.1 mrg cout << " want_si: " << want_si << "\n";
181 1.1 mrg }
182 1.1.1.1.2.1 yamt if (want_ok && got_eof != want_eof)
183 1.1.1.1.2.1 yamt {
184 1.1.1.1.2.1 yamt WRONG ("stdc++ operator>> wrong EOF state, check_mpz");
185 1.1.1.1.2.1 yamt cout << " got_eof: " << got_eof << "\n";
186 1.1.1.1.2.1 yamt cout << " want_eof: " << want_eof << "\n";
187 1.1.1.1.2.1 yamt }
188 1.1 mrg if (putback_tellg_works && got_pos != want_pos)
189 1.1 mrg {
190 1.1 mrg WRONG ("stdc++ operator>> wrong position, check_mpz");
191 1.1 mrg cout << " want_pos: " << want_pos << "\n";
192 1.1 mrg cout << " got_pos: " << got_pos << "\n";
193 1.1 mrg }
194 1.1 mrg }
195 1.1 mrg
196 1.1 mrg {
197 1.1 mrg istringstream input (data[i].input);
198 1.1 mrg input.flags (data[i].flags);
199 1.1 mrg init_tellg = input.tellg();
200 1.1 mrg
201 1.1 mrg mpz_set_ui (got, 0xDEAD);
202 1.1 mrg input >> got;
203 1.1.1.1.2.1 yamt got_ok = !input.fail();
204 1.1.1.1.2.1 yamt got_eof = input.eof();
205 1.1 mrg input.clear();
206 1.1 mrg got_pos = input.tellg() - init_tellg;
207 1.1 mrg
208 1.1 mrg if (got_ok != want_ok)
209 1.1 mrg {
210 1.1 mrg WRONG ("mpz operator>> wrong status");
211 1.1 mrg cout << " want_ok: " << want_ok << "\n";
212 1.1 mrg cout << " got_ok: " << got_ok << "\n";
213 1.1 mrg abort ();
214 1.1 mrg }
215 1.1 mrg if (want_ok && mpz_cmp (got, want) != 0)
216 1.1 mrg {
217 1.1 mrg WRONG ("mpz operator>> wrong result");
218 1.1 mrg mpz_trace (" got ", got);
219 1.1 mrg mpz_trace (" want", want);
220 1.1 mrg abort ();
221 1.1 mrg }
222 1.1.1.1.2.1 yamt if (want_ok && got_eof != want_eof)
223 1.1.1.1.2.1 yamt {
224 1.1.1.1.2.1 yamt WRONG ("mpz operator>> wrong EOF state");
225 1.1.1.1.2.1 yamt cout << " want_eof: " << want_eof << "\n";
226 1.1.1.1.2.1 yamt cout << " got_eof: " << got_eof << "\n";
227 1.1.1.1.2.1 yamt abort ();
228 1.1.1.1.2.1 yamt }
229 1.1 mrg if (putback_tellg_works && got_pos != want_pos)
230 1.1 mrg {
231 1.1 mrg WRONG ("mpz operator>> wrong position");
232 1.1 mrg cout << " want_pos: " << want_pos << "\n";
233 1.1 mrg cout << " got_pos: " << got_pos << "\n";
234 1.1 mrg abort ();
235 1.1 mrg }
236 1.1 mrg }
237 1.1 mrg }
238 1.1 mrg
239 1.1 mrg mpz_clear (got);
240 1.1 mrg mpz_clear (want);
241 1.1 mrg }
242 1.1 mrg
243 1.1 mrg void
244 1.1 mrg check_mpq (void)
245 1.1 mrg {
246 1.1 mrg static const struct {
247 1.1 mrg const char *input;
248 1.1 mrg int want_pos;
249 1.1 mrg const char *want;
250 1.1 mrg ios::fmtflags flags;
251 1.1 mrg
252 1.1 mrg } data[] = {
253 1.1 mrg
254 1.1 mrg { "0", -1, "0", (ios::fmtflags) 0 },
255 1.1 mrg { "00", -1, "0", (ios::fmtflags) 0 },
256 1.1 mrg { "0x0", -1, "0", (ios::fmtflags) 0 },
257 1.1 mrg
258 1.1 mrg { "123/456", -1, "123/456", ios::dec },
259 1.1 mrg { "0123/456", -1, "123/456", ios::dec },
260 1.1 mrg { "123/0456", -1, "123/456", ios::dec },
261 1.1 mrg { "0123/0456", -1, "123/456", ios::dec },
262 1.1 mrg
263 1.1 mrg { "123/456", -1, "83/302", ios::oct },
264 1.1 mrg { "0123/456", -1, "83/302", ios::oct },
265 1.1 mrg { "123/0456", -1, "83/302", ios::oct },
266 1.1 mrg { "0123/0456", -1, "83/302", ios::oct },
267 1.1 mrg
268 1.1 mrg { "ab", -1, "171", ios::hex },
269 1.1 mrg { "cd", -1, "205", ios::hex },
270 1.1 mrg { "ef", -1, "239", ios::hex },
271 1.1 mrg
272 1.1 mrg { "0/0", -1, "0/0", (ios::fmtflags) 0 },
273 1.1 mrg { "5/8", -1, "5/8", (ios::fmtflags) 0 },
274 1.1 mrg { "0x5/0x8", -1, "5/8", (ios::fmtflags) 0 },
275 1.1 mrg
276 1.1 mrg { "123/456", -1, "123/456", (ios::fmtflags) 0 },
277 1.1 mrg { "123/0456", -1, "123/302", (ios::fmtflags) 0 },
278 1.1 mrg { "123/0x456", -1, "123/1110", (ios::fmtflags) 0 },
279 1.1 mrg { "123/0X456", -1, "123/1110", (ios::fmtflags) 0 },
280 1.1 mrg
281 1.1 mrg { "0123/123", -1, "83/123", (ios::fmtflags) 0 },
282 1.1 mrg { "0123/0123", -1, "83/83", (ios::fmtflags) 0 },
283 1.1 mrg { "0123/0x123", -1, "83/291", (ios::fmtflags) 0 },
284 1.1 mrg { "0123/0X123", -1, "83/291", (ios::fmtflags) 0 },
285 1.1 mrg
286 1.1 mrg { "0x123/123", -1, "291/123", (ios::fmtflags) 0 },
287 1.1 mrg { "0X123/0123", -1, "291/83", (ios::fmtflags) 0 },
288 1.1 mrg { "0x123/0x123", -1, "291/291", (ios::fmtflags) 0 },
289 1.1 mrg
290 1.1 mrg { " 123", 0, NULL, (ios::fmtflags) 0 }, // not without skipws
291 1.1 mrg { " 123", -1, "123", ios::skipws },
292 1.1.1.1.2.1 yamt
293 1.1.1.1.2.1 yamt { "123 /456", 3, "123", (ios::fmtflags) 0 },
294 1.1.1.1.2.1 yamt { "123/ 456", 4, NULL, (ios::fmtflags) 0 },
295 1.1.1.1.2.1 yamt { "123/" , -1, NULL, (ios::fmtflags) 0 },
296 1.1.1.1.2.1 yamt { "123 /456", 3, "123", ios::skipws },
297 1.1.1.1.2.1 yamt { "123/ 456", 4, NULL, ios::skipws },
298 1.1 mrg };
299 1.1 mrg
300 1.1 mrg mpq_t got, want;
301 1.1.1.1.2.1 yamt bool got_ok, want_ok;
302 1.1.1.1.2.1 yamt bool got_eof, want_eof;
303 1.1 mrg long got_si, want_si;
304 1.1 mrg streampos init_tellg, got_pos, want_pos;
305 1.1 mrg
306 1.1 mrg mpq_init (got);
307 1.1 mrg mpq_init (want);
308 1.1 mrg
309 1.1 mrg for (size_t i = 0; i < numberof (data); i++)
310 1.1 mrg {
311 1.1.1.1.2.1 yamt size_t input_length = strlen (data[i].input);
312 1.1 mrg want_pos = (data[i].want_pos == -1
313 1.1.1.1.2.1 yamt ? input_length : data[i].want_pos);
314 1.1.1.1.2.1 yamt want_eof = (want_pos == streampos(input_length));
315 1.1 mrg
316 1.1 mrg want_ok = (data[i].want != NULL);
317 1.1 mrg
318 1.1 mrg if (data[i].want != NULL)
319 1.1 mrg mpq_set_str_or_abort (want, data[i].want, 0);
320 1.1 mrg else
321 1.1 mrg mpq_set_ui (want, 0L, 1L);
322 1.1 mrg
323 1.1 mrg if (option_check_standard
324 1.1 mrg && mpz_fits_slong_p (mpq_numref(want))
325 1.1.1.1.2.1 yamt && mpz_cmp_ui (mpq_denref(want), 1L) == 0
326 1.1.1.1.2.1 yamt && strchr (data[i].input, '/') == NULL)
327 1.1 mrg {
328 1.1 mrg istringstream input (data[i].input);
329 1.1 mrg input.flags (data[i].flags);
330 1.1 mrg init_tellg = input.tellg();
331 1.1 mrg want_si = mpz_get_si (mpq_numref(want));
332 1.1 mrg
333 1.1 mrg input >> got_si;
334 1.1.1.1.2.1 yamt got_ok = !input.fail();
335 1.1.1.1.2.1 yamt got_eof = input.eof();
336 1.1 mrg input.clear();
337 1.1 mrg got_pos = input.tellg() - init_tellg;
338 1.1 mrg
339 1.1 mrg if (got_ok != want_ok)
340 1.1 mrg {
341 1.1 mrg WRONG ("stdc++ operator>> wrong status, check_mpq");
342 1.1 mrg cout << " want_ok: " << want_ok << "\n";
343 1.1 mrg cout << " got_ok: " << got_ok << "\n";
344 1.1 mrg }
345 1.1 mrg if (want_ok && want_si != got_si)
346 1.1 mrg {
347 1.1 mrg WRONG ("stdc++ operator>> wrong result, check_mpq");
348 1.1 mrg cout << " got_si: " << got_si << "\n";
349 1.1 mrg cout << " want_si: " << want_si << "\n";
350 1.1 mrg }
351 1.1.1.1.2.1 yamt if (want_ok && got_eof != want_eof)
352 1.1.1.1.2.1 yamt {
353 1.1.1.1.2.1 yamt WRONG ("stdc++ operator>> wrong EOF state, check_mpq");
354 1.1.1.1.2.1 yamt cout << " got_eof: " << got_eof << "\n";
355 1.1.1.1.2.1 yamt cout << " want_eof: " << want_eof << "\n";
356 1.1.1.1.2.1 yamt }
357 1.1 mrg if (putback_tellg_works && got_pos != want_pos)
358 1.1 mrg {
359 1.1 mrg WRONG ("stdc++ operator>> wrong position, check_mpq");
360 1.1 mrg cout << " want_pos: " << want_pos << "\n";
361 1.1 mrg cout << " got_pos: " << got_pos << "\n";
362 1.1 mrg }
363 1.1 mrg }
364 1.1 mrg
365 1.1 mrg {
366 1.1 mrg istringstream input (data[i].input);
367 1.1 mrg input.flags (data[i].flags);
368 1.1 mrg init_tellg = input.tellg();
369 1.1 mrg mpq_set_si (got, 0xDEAD, 0xBEEF);
370 1.1 mrg
371 1.1 mrg input >> got;
372 1.1.1.1.2.1 yamt got_ok = !input.fail();
373 1.1.1.1.2.1 yamt got_eof = input.eof();
374 1.1 mrg input.clear();
375 1.1 mrg got_pos = input.tellg() - init_tellg;
376 1.1 mrg
377 1.1 mrg if (got_ok != want_ok)
378 1.1 mrg {
379 1.1 mrg WRONG ("mpq operator>> wrong status");
380 1.1 mrg cout << " want_ok: " << want_ok << "\n";
381 1.1 mrg cout << " got_ok: " << got_ok << "\n";
382 1.1 mrg abort ();
383 1.1 mrg }
384 1.1 mrg // don't use mpq_equal, since we allow non-normalized values to be
385 1.1 mrg // read, which can trigger ASSERTs in mpq_equal
386 1.1 mrg if (want_ok && (mpz_cmp (mpq_numref (got), mpq_numref(want)) != 0
387 1.1 mrg || mpz_cmp (mpq_denref (got), mpq_denref(want)) != 0))
388 1.1 mrg {
389 1.1 mrg WRONG ("mpq operator>> wrong result");
390 1.1 mrg mpq_trace (" got ", got);
391 1.1 mrg mpq_trace (" want", want);
392 1.1 mrg abort ();
393 1.1 mrg }
394 1.1.1.1.2.1 yamt if (want_ok && got_eof != want_eof)
395 1.1.1.1.2.1 yamt {
396 1.1.1.1.2.1 yamt WRONG ("mpq operator>> wrong EOF state");
397 1.1.1.1.2.1 yamt cout << " want_eof: " << want_eof << "\n";
398 1.1.1.1.2.1 yamt cout << " got_eof: " << got_eof << "\n";
399 1.1.1.1.2.1 yamt abort ();
400 1.1.1.1.2.1 yamt }
401 1.1 mrg if (putback_tellg_works && got_pos != want_pos)
402 1.1 mrg {
403 1.1 mrg WRONG ("mpq operator>> wrong position");
404 1.1 mrg cout << " want_pos: " << want_pos << "\n";
405 1.1 mrg cout << " got_pos: " << got_pos << "\n";
406 1.1 mrg abort ();
407 1.1 mrg }
408 1.1 mrg }
409 1.1 mrg }
410 1.1 mrg
411 1.1 mrg mpq_clear (got);
412 1.1 mrg mpq_clear (want);
413 1.1 mrg }
414 1.1 mrg
415 1.1 mrg
416 1.1 mrg void
417 1.1 mrg check_mpf (void)
418 1.1 mrg {
419 1.1 mrg static const struct {
420 1.1 mrg const char *input;
421 1.1 mrg int want_pos;
422 1.1 mrg const char *want;
423 1.1 mrg ios::fmtflags flags;
424 1.1 mrg
425 1.1 mrg } data[] = {
426 1.1 mrg
427 1.1 mrg { "0", -1, "0", (ios::fmtflags) 0 },
428 1.1 mrg { "+0", -1, "0", (ios::fmtflags) 0 },
429 1.1 mrg { "-0", -1, "0", (ios::fmtflags) 0 },
430 1.1 mrg { "0.0", -1, "0", (ios::fmtflags) 0 },
431 1.1 mrg { "0.", -1, "0", (ios::fmtflags) 0 },
432 1.1 mrg { ".0", -1, "0", (ios::fmtflags) 0 },
433 1.1 mrg { "+.0", -1, "0", (ios::fmtflags) 0 },
434 1.1 mrg { "-.0", -1, "0", (ios::fmtflags) 0 },
435 1.1 mrg { "+0.00", -1, "0", (ios::fmtflags) 0 },
436 1.1 mrg { "-0.000", -1, "0", (ios::fmtflags) 0 },
437 1.1 mrg { "+0.00", -1, "0", (ios::fmtflags) 0 },
438 1.1 mrg { "-0.000", -1, "0", (ios::fmtflags) 0 },
439 1.1 mrg { "0.0e0", -1, "0", (ios::fmtflags) 0 },
440 1.1 mrg { "0.e0", -1, "0", (ios::fmtflags) 0 },
441 1.1 mrg { ".0e0", -1, "0", (ios::fmtflags) 0 },
442 1.1 mrg { "0.0e-0", -1, "0", (ios::fmtflags) 0 },
443 1.1 mrg { "0.e-0", -1, "0", (ios::fmtflags) 0 },
444 1.1 mrg { ".0e-0", -1, "0", (ios::fmtflags) 0 },
445 1.1 mrg { "0.0e+0", -1, "0", (ios::fmtflags) 0 },
446 1.1 mrg { "0.e+0", -1, "0", (ios::fmtflags) 0 },
447 1.1 mrg { ".0e+0", -1, "0", (ios::fmtflags) 0 },
448 1.1 mrg
449 1.1 mrg { "1", -1, "1", (ios::fmtflags) 0 },
450 1.1 mrg { "+1", -1, "1", (ios::fmtflags) 0 },
451 1.1 mrg { "-1", -1, "-1", (ios::fmtflags) 0 },
452 1.1 mrg
453 1.1 mrg { " 0", 0, NULL, (ios::fmtflags) 0 }, // not without skipws
454 1.1 mrg { " 0", -1, "0", ios::skipws },
455 1.1 mrg { " +0", -1, "0", ios::skipws },
456 1.1 mrg { " -0", -1, "0", ios::skipws },
457 1.1 mrg
458 1.1 mrg { "+-123", 1, NULL, (ios::fmtflags) 0 },
459 1.1 mrg { "-+123", 1, NULL, (ios::fmtflags) 0 },
460 1.1 mrg { "1e+-123", 3, NULL, (ios::fmtflags) 0 },
461 1.1 mrg { "1e-+123", 3, NULL, (ios::fmtflags) 0 },
462 1.1 mrg
463 1.1 mrg { "e123", 0, NULL, (ios::fmtflags) 0 }, // at least one mantissa digit
464 1.1 mrg { ".e123", 1, NULL, (ios::fmtflags) 0 },
465 1.1 mrg { "+.e123", 2, NULL, (ios::fmtflags) 0 },
466 1.1 mrg { "-.e123", 2, NULL, (ios::fmtflags) 0 },
467 1.1 mrg
468 1.1 mrg { "123e", 4, NULL, (ios::fmtflags) 0 }, // at least one exponent digit
469 1.1 mrg { "123e-", 5, NULL, (ios::fmtflags) 0 },
470 1.1 mrg { "123e+", 5, NULL, (ios::fmtflags) 0 },
471 1.1 mrg };
472 1.1 mrg
473 1.1 mrg mpf_t got, want;
474 1.1.1.1.2.1 yamt bool got_ok, want_ok;
475 1.1.1.1.2.1 yamt bool got_eof, want_eof;
476 1.1 mrg double got_d, want_d;
477 1.1 mrg streampos init_tellg, got_pos, want_pos;
478 1.1 mrg
479 1.1 mrg mpf_init (got);
480 1.1 mrg mpf_init (want);
481 1.1 mrg
482 1.1 mrg for (size_t i = 0; i < numberof (data); i++)
483 1.1 mrg {
484 1.1.1.1.2.1 yamt size_t input_length = strlen (data[i].input);
485 1.1 mrg want_pos = (data[i].want_pos == -1
486 1.1.1.1.2.1 yamt ? input_length : data[i].want_pos);
487 1.1.1.1.2.1 yamt want_eof = (want_pos == streampos(input_length));
488 1.1 mrg
489 1.1 mrg want_ok = (data[i].want != NULL);
490 1.1 mrg
491 1.1 mrg if (data[i].want != NULL)
492 1.1 mrg mpf_set_str_or_abort (want, data[i].want, 0);
493 1.1 mrg else
494 1.1 mrg mpf_set_ui (want, 0L);
495 1.1 mrg
496 1.1 mrg want_d = mpf_get_d (want);
497 1.1 mrg if (option_check_standard && mpf_cmp_d (want, want_d) == 0)
498 1.1 mrg {
499 1.1 mrg istringstream input (data[i].input);
500 1.1 mrg input.flags (data[i].flags);
501 1.1 mrg init_tellg = input.tellg();
502 1.1 mrg
503 1.1 mrg input >> got_d;
504 1.1.1.1.2.1 yamt got_ok = !input.fail();
505 1.1.1.1.2.1 yamt got_eof = input.eof();
506 1.1 mrg input.clear();
507 1.1 mrg got_pos = input.tellg() - init_tellg;
508 1.1 mrg
509 1.1 mrg if (got_ok != want_ok)
510 1.1 mrg {
511 1.1 mrg WRONG ("stdc++ operator>> wrong status, check_mpf");
512 1.1 mrg cout << " want_ok: " << want_ok << "\n";
513 1.1 mrg cout << " got_ok: " << got_ok << "\n";
514 1.1 mrg }
515 1.1 mrg if (want_ok && want_d != got_d)
516 1.1 mrg {
517 1.1 mrg WRONG ("stdc++ operator>> wrong result, check_mpf");
518 1.1 mrg cout << " got: " << got_d << "\n";
519 1.1 mrg cout << " want: " << want_d << "\n";
520 1.1 mrg }
521 1.1.1.1.2.1 yamt if (want_ok && got_eof != want_eof)
522 1.1.1.1.2.1 yamt {
523 1.1.1.1.2.1 yamt WRONG ("stdc++ operator>> wrong EOF state, check_mpf");
524 1.1.1.1.2.1 yamt cout << " got_eof: " << got_eof << "\n";
525 1.1.1.1.2.1 yamt cout << " want_eof: " << want_eof << "\n";
526 1.1.1.1.2.1 yamt }
527 1.1 mrg if (putback_tellg_works && got_pos != want_pos)
528 1.1 mrg {
529 1.1 mrg WRONG ("stdc++ operator>> wrong position, check_mpf");
530 1.1 mrg cout << " want_pos: " << want_pos << "\n";
531 1.1 mrg cout << " got_pos: " << got_pos << "\n";
532 1.1 mrg }
533 1.1 mrg }
534 1.1 mrg
535 1.1 mrg {
536 1.1 mrg istringstream input (data[i].input);
537 1.1 mrg input.flags (data[i].flags);
538 1.1 mrg init_tellg = input.tellg();
539 1.1 mrg
540 1.1 mrg mpf_set_ui (got, 0xDEAD);
541 1.1 mrg input >> got;
542 1.1.1.1.2.1 yamt got_ok = !input.fail();
543 1.1.1.1.2.1 yamt got_eof = input.eof();
544 1.1 mrg input.clear();
545 1.1 mrg got_pos = input.tellg() - init_tellg;
546 1.1 mrg
547 1.1 mrg if (got_ok != want_ok)
548 1.1 mrg {
549 1.1 mrg WRONG ("mpf operator>> wrong status");
550 1.1 mrg cout << " want_ok: " << want_ok << "\n";
551 1.1 mrg cout << " got_ok: " << got_ok << "\n";
552 1.1 mrg abort ();
553 1.1 mrg }
554 1.1 mrg if (want_ok && mpf_cmp (got, want) != 0)
555 1.1 mrg {
556 1.1 mrg WRONG ("mpf operator>> wrong result");
557 1.1 mrg mpf_trace (" got ", got);
558 1.1 mrg mpf_trace (" want", want);
559 1.1 mrg abort ();
560 1.1 mrg }
561 1.1.1.1.2.1 yamt if (want_ok && got_eof != want_eof)
562 1.1.1.1.2.1 yamt {
563 1.1.1.1.2.1 yamt WRONG ("mpf operator>> wrong EOF state");
564 1.1.1.1.2.1 yamt cout << " want_eof: " << want_eof << "\n";
565 1.1.1.1.2.1 yamt cout << " got_eof: " << got_eof << "\n";
566 1.1.1.1.2.1 yamt abort ();
567 1.1.1.1.2.1 yamt }
568 1.1 mrg if (putback_tellg_works && got_pos != want_pos)
569 1.1 mrg {
570 1.1 mrg WRONG ("mpf operator>> wrong position");
571 1.1 mrg cout << " want_pos: " << want_pos << "\n";
572 1.1 mrg cout << " got_pos: " << got_pos << "\n";
573 1.1 mrg abort ();
574 1.1 mrg }
575 1.1 mrg }
576 1.1 mrg }
577 1.1 mrg
578 1.1 mrg mpf_clear (got);
579 1.1 mrg mpf_clear (want);
580 1.1 mrg }
581 1.1 mrg
582 1.1 mrg
583 1.1 mrg
584 1.1 mrg int
585 1.1 mrg main (int argc, char *argv[])
586 1.1 mrg {
587 1.1 mrg if (argc > 1 && strcmp (argv[1], "-s") == 0)
588 1.1.1.1.2.1 yamt option_check_standard = true;
589 1.1 mrg
590 1.1 mrg tests_start ();
591 1.1 mrg
592 1.1 mrg check_putback_tellg ();
593 1.1 mrg check_mpz ();
594 1.1 mrg check_mpq ();
595 1.1 mrg check_mpf ();
596 1.1 mrg
597 1.1 mrg tests_end ();
598 1.1 mrg return 0;
599 1.1 mrg }
600