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