t-istream.cc
上传用户:qaz666999
上传日期:2022-08-06
资源大小:2570k
文件大小:16k
- /* Test istream formatted input.
- Copyright 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
- This file is part of the GNU MP Library.
- The GNU MP Library is free software; you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 3 of the License, or (at your
- option) any later version.
- The GNU MP Library is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
- License for more details.
- You should have received a copy of the GNU Lesser General Public License
- along with the GNU MP Library. If not, see http://www.gnu.org/licenses/. */
- #include <iostream>
- #include <cstdlib>
- #include <cstring>
- #include "gmp.h"
- #include "gmp-impl.h"
- #include "tests.h"
- using namespace std;
- // Under option_check_standard, the various test cases for mpz operator>>
- // are put through the standard operator>> for long, and likewise mpf
- // operator>> is put through double.
- //
- // In g++ 3.3 this results in some printouts about the final position
- // indicated for something like ".e123". Our mpf code stops at the "e"
- // since there's no mantissa digits, but g++ reads the whole thing and only
- // then decides it's bad.
- int option_check_standard = 0;
- // On some versions of g++ 2.96 it's been observed that putback() may leave
- // tellg() unchanged. We believe this is incorrect and presumably the
- // result of a bug, since for instance it's ok in g++ 2.95 and g++ 3.3. We
- // detect the problem at runtime and disable affected checks.
- int putback_tellg_works = 1;
- void
- check_putback_tellg (void)
- {
- istringstream input ("hello");
- streampos old_pos, new_pos;
- char c;
- input.get(c);
- old_pos = input.tellg();
- input.putback(c);
- new_pos = input.tellg();
- if (old_pos == new_pos)
- {
- cout << "Warning, istringstream has a bug: putback() doesn't update tellg().n";;
- cout << "Tests on tellg() will be skipped.n";
- putback_tellg_works = 0;
- }
- }
- #define WRONG(str)
- do {
- cout << str ", data[" << i << "]n";
- cout << " input: "" << data[i].input << ""n";
- cout << " flags: " << hex << input.flags() << dec << "n";
- } while (0)
- void
- check_mpz (void)
- {
- static const struct {
- const char *input;
- int want_pos;
- const char *want;
- ios::fmtflags flags;
- } data[] = {
- { "0", -1, "0", (ios::fmtflags) 0 },
- { "123", -1, "123", (ios::fmtflags) 0 },
- { "0123", -1, "83", (ios::fmtflags) 0 },
- { "0x123", -1, "291", (ios::fmtflags) 0 },
- { "-123", -1, "-123", (ios::fmtflags) 0 },
- { "-0123", -1, "-83", (ios::fmtflags) 0 },
- { "-0x123", -1, "-291", (ios::fmtflags) 0 },
- { "+123", -1, "123", (ios::fmtflags) 0 },
- { "+0123", -1, "83", (ios::fmtflags) 0 },
- { "+0x123", -1, "291", (ios::fmtflags) 0 },
- { "0", -1, "0", ios::dec },
- { "1f", 1, "1", ios::dec },
- { "011f", 3, "11", ios::dec },
- { "123", -1, "123", ios::dec },
- { "-1f", 2, "-1", ios::dec },
- { "-011f", 4, "-11", ios::dec },
- { "-123", -1, "-123", ios::dec },
- { "+1f", 2, "1", ios::dec },
- { "+011f", 4, "11", ios::dec },
- { "+123", -1, "123", ios::dec },
- { "0", -1, "0", ios::oct },
- { "123", -1, "83", ios::oct },
- { "-123", -1, "-83", ios::oct },
- { "+123", -1, "83", ios::oct },
- { "0", -1, "0", ios::hex },
- { "123", -1, "291", ios::hex },
- { "ff", -1, "255", ios::hex },
- { "FF", -1, "255", ios::hex },
- { "-123", -1, "-291", ios::hex },
- { "-ff", -1, "-255", ios::hex },
- { "-FF", -1, "-255", ios::hex },
- { "+123", -1, "291", ios::hex },
- { "+ff", -1, "255", ios::hex },
- { "+FF", -1, "255", ios::hex },
- { "ab", -1, "171", ios::hex },
- { "cd", -1, "205", ios::hex },
- { "ef", -1, "239", ios::hex },
- { " 123", 0, NULL, (ios::fmtflags) 0 }, // not without skipws
- { " 123", -1, "123", ios::skipws },
- };
- mpz_t got, want;
- int got_ok, want_ok;
- long got_si, want_si;
- streampos init_tellg, got_pos, want_pos;
- mpz_init (got);
- mpz_init (want);
- for (size_t i = 0; i < numberof (data); i++)
- {
- want_pos = (data[i].want_pos == -1
- ? strlen (data[i].input) : data[i].want_pos);
- want_ok = (data[i].want != NULL);
- if (data[i].want != NULL)
- mpz_set_str_or_abort (want, data[i].want, 0);
- else
- mpz_set_ui (want, 0L);
- if (option_check_standard && mpz_fits_slong_p (want))
- {
- istringstream input (data[i].input);
- input.flags (data[i].flags);
- init_tellg = input.tellg();
- want_si = mpz_get_si (want);
- input >> got_si;
- got_ok = (input ? 1 : 0);
- input.clear();
- got_pos = input.tellg() - init_tellg;
- if (got_ok != want_ok)
- {
- WRONG ("stdc++ operator>> wrong status, check_mpz");
- cout << " want_ok: " << want_ok << "n";
- cout << " got_ok: " << got_ok << "n";
- }
- if (want_ok && got_si != want_si)
- {
- WRONG ("stdc++ operator>> wrong result, check_mpz");
- cout << " got_si: " << got_si << "n";
- cout << " want_si: " << want_si << "n";
- }
- if (putback_tellg_works && got_pos != want_pos)
- {
- WRONG ("stdc++ operator>> wrong position, check_mpz");
- cout << " want_pos: " << want_pos << "n";
- cout << " got_pos: " << got_pos << "n";
- }
- }
- {
- istringstream input (data[i].input);
- input.flags (data[i].flags);
- init_tellg = input.tellg();
- mpz_set_ui (got, 0xDEAD);
- input >> got;
- got_ok = (input ? 1 : 0);
- input.clear();
- got_pos = input.tellg() - init_tellg;
- if (got_ok != want_ok)
- {
- WRONG ("mpz operator>> wrong status");
- cout << " want_ok: " << want_ok << "n";
- cout << " got_ok: " << got_ok << "n";
- abort ();
- }
- if (want_ok && mpz_cmp (got, want) != 0)
- {
- WRONG ("mpz operator>> wrong result");
- mpz_trace (" got ", got);
- mpz_trace (" want", want);
- abort ();
- }
- if (putback_tellg_works && got_pos != want_pos)
- {
- WRONG ("mpz operator>> wrong position");
- cout << " want_pos: " << want_pos << "n";
- cout << " got_pos: " << got_pos << "n";
- abort ();
- }
- }
- }
- mpz_clear (got);
- mpz_clear (want);
- }
- void
- check_mpq (void)
- {
- static const struct {
- const char *input;
- int want_pos;
- const char *want;
- ios::fmtflags flags;
- } data[] = {
- { "0", -1, "0", (ios::fmtflags) 0 },
- { "00", -1, "0", (ios::fmtflags) 0 },
- { "0x0", -1, "0", (ios::fmtflags) 0 },
- { "123/456", -1, "123/456", ios::dec },
- { "0123/456", -1, "123/456", ios::dec },
- { "123/0456", -1, "123/456", ios::dec },
- { "0123/0456", -1, "123/456", ios::dec },
- { "123/456", -1, "83/302", ios::oct },
- { "0123/456", -1, "83/302", ios::oct },
- { "123/0456", -1, "83/302", ios::oct },
- { "0123/0456", -1, "83/302", ios::oct },
- { "ab", -1, "171", ios::hex },
- { "cd", -1, "205", ios::hex },
- { "ef", -1, "239", ios::hex },
- { "0/0", -1, "0/0", (ios::fmtflags) 0 },
- { "5/8", -1, "5/8", (ios::fmtflags) 0 },
- { "0x5/0x8", -1, "5/8", (ios::fmtflags) 0 },
- { "123/456", -1, "123/456", (ios::fmtflags) 0 },
- { "123/0456", -1, "123/302", (ios::fmtflags) 0 },
- { "123/0x456", -1, "123/1110", (ios::fmtflags) 0 },
- { "123/0X456", -1, "123/1110", (ios::fmtflags) 0 },
- { "0123/123", -1, "83/123", (ios::fmtflags) 0 },
- { "0123/0123", -1, "83/83", (ios::fmtflags) 0 },
- { "0123/0x123", -1, "83/291", (ios::fmtflags) 0 },
- { "0123/0X123", -1, "83/291", (ios::fmtflags) 0 },
- { "0x123/123", -1, "291/123", (ios::fmtflags) 0 },
- { "0X123/0123", -1, "291/83", (ios::fmtflags) 0 },
- { "0x123/0x123", -1, "291/291", (ios::fmtflags) 0 },
- { " 123", 0, NULL, (ios::fmtflags) 0 }, // not without skipws
- { " 123", -1, "123", ios::skipws },
- };
- mpq_t got, want;
- int got_ok, want_ok;
- long got_si, want_si;
- streampos init_tellg, got_pos, want_pos;
- mpq_init (got);
- mpq_init (want);
- for (size_t i = 0; i < numberof (data); i++)
- {
- want_pos = (data[i].want_pos == -1
- ? strlen (data[i].input) : data[i].want_pos);
- want_ok = (data[i].want != NULL);
- if (data[i].want != NULL)
- mpq_set_str_or_abort (want, data[i].want, 0);
- else
- mpq_set_ui (want, 0L, 1L);
- if (option_check_standard
- && mpz_fits_slong_p (mpq_numref(want))
- && mpz_cmp_ui (mpq_denref(want), 1L) == 0)
- {
- istringstream input (data[i].input);
- input.flags (data[i].flags);
- init_tellg = input.tellg();
- want_si = mpz_get_si (mpq_numref(want));
- input >> got_si;
- got_ok = (input ? 1 : 0);
- input.clear();
- got_pos = input.tellg() - init_tellg;
- if (got_ok != want_ok)
- {
- WRONG ("stdc++ operator>> wrong status, check_mpq");
- cout << " want_ok: " << want_ok << "n";
- cout << " got_ok: " << got_ok << "n";
- }
- if (want_ok && want_si != got_si)
- {
- WRONG ("stdc++ operator>> wrong result, check_mpq");
- cout << " got_si: " << got_si << "n";
- cout << " want_si: " << want_si << "n";
- }
- if (putback_tellg_works && got_pos != want_pos)
- {
- WRONG ("stdc++ operator>> wrong position, check_mpq");
- cout << " want_pos: " << want_pos << "n";
- cout << " got_pos: " << got_pos << "n";
- }
- }
- {
- istringstream input (data[i].input);
- input.flags (data[i].flags);
- init_tellg = input.tellg();
- mpq_set_si (got, 0xDEAD, 0xBEEF);
- input >> got;
- got_ok = (input ? 1 : 0);
- input.clear();
- got_pos = input.tellg() - init_tellg;
- if (got_ok != want_ok)
- {
- WRONG ("mpq operator>> wrong status");
- cout << " want_ok: " << want_ok << "n";
- cout << " got_ok: " << got_ok << "n";
- abort ();
- }
- // don't use mpq_equal, since we allow non-normalized values to be
- // read, which can trigger ASSERTs in mpq_equal
- if (want_ok && (mpz_cmp (mpq_numref (got), mpq_numref(want)) != 0
- || mpz_cmp (mpq_denref (got), mpq_denref(want)) != 0))
- {
- WRONG ("mpq operator>> wrong result");
- mpq_trace (" got ", got);
- mpq_trace (" want", want);
- abort ();
- }
- if (putback_tellg_works && got_pos != want_pos)
- {
- WRONG ("mpq operator>> wrong position");
- cout << " want_pos: " << want_pos << "n";
- cout << " got_pos: " << got_pos << "n";
- abort ();
- }
- }
- }
- mpq_clear (got);
- mpq_clear (want);
- }
- void
- check_mpf (void)
- {
- static const struct {
- const char *input;
- int want_pos;
- const char *want;
- ios::fmtflags flags;
- } data[] = {
- { "0", -1, "0", (ios::fmtflags) 0 },
- { "+0", -1, "0", (ios::fmtflags) 0 },
- { "-0", -1, "0", (ios::fmtflags) 0 },
- { "0.0", -1, "0", (ios::fmtflags) 0 },
- { "0.", -1, "0", (ios::fmtflags) 0 },
- { ".0", -1, "0", (ios::fmtflags) 0 },
- { "+.0", -1, "0", (ios::fmtflags) 0 },
- { "-.0", -1, "0", (ios::fmtflags) 0 },
- { "+0.00", -1, "0", (ios::fmtflags) 0 },
- { "-0.000", -1, "0", (ios::fmtflags) 0 },
- { "+0.00", -1, "0", (ios::fmtflags) 0 },
- { "-0.000", -1, "0", (ios::fmtflags) 0 },
- { "0.0e0", -1, "0", (ios::fmtflags) 0 },
- { "0.e0", -1, "0", (ios::fmtflags) 0 },
- { ".0e0", -1, "0", (ios::fmtflags) 0 },
- { "0.0e-0", -1, "0", (ios::fmtflags) 0 },
- { "0.e-0", -1, "0", (ios::fmtflags) 0 },
- { ".0e-0", -1, "0", (ios::fmtflags) 0 },
- { "0.0e+0", -1, "0", (ios::fmtflags) 0 },
- { "0.e+0", -1, "0", (ios::fmtflags) 0 },
- { ".0e+0", -1, "0", (ios::fmtflags) 0 },
- { "1", -1, "1", (ios::fmtflags) 0 },
- { "+1", -1, "1", (ios::fmtflags) 0 },
- { "-1", -1, "-1", (ios::fmtflags) 0 },
- { " 0", 0, NULL, (ios::fmtflags) 0 }, // not without skipws
- { " 0", -1, "0", ios::skipws },
- { " +0", -1, "0", ios::skipws },
- { " -0", -1, "0", ios::skipws },
- { "+-123", 1, NULL, (ios::fmtflags) 0 },
- { "-+123", 1, NULL, (ios::fmtflags) 0 },
- { "1e+-123", 3, NULL, (ios::fmtflags) 0 },
- { "1e-+123", 3, NULL, (ios::fmtflags) 0 },
- { "e123", 0, NULL, (ios::fmtflags) 0 }, // at least one mantissa digit
- { ".e123", 1, NULL, (ios::fmtflags) 0 },
- { "+.e123", 2, NULL, (ios::fmtflags) 0 },
- { "-.e123", 2, NULL, (ios::fmtflags) 0 },
- { "123e", 4, NULL, (ios::fmtflags) 0 }, // at least one exponent digit
- { "123e-", 5, NULL, (ios::fmtflags) 0 },
- { "123e+", 5, NULL, (ios::fmtflags) 0 },
- };
- mpf_t got, want;
- int got_ok, want_ok;
- double got_d, want_d;
- streampos init_tellg, got_pos, want_pos;
- mpf_init (got);
- mpf_init (want);
- for (size_t i = 0; i < numberof (data); i++)
- {
- want_pos = (data[i].want_pos == -1
- ? strlen (data[i].input) : data[i].want_pos);
- want_ok = (data[i].want != NULL);
- if (data[i].want != NULL)
- mpf_set_str_or_abort (want, data[i].want, 0);
- else
- mpf_set_ui (want, 0L);
- want_d = mpf_get_d (want);
- if (option_check_standard && mpf_cmp_d (want, want_d) == 0)
- {
- istringstream input (data[i].input);
- input.flags (data[i].flags);
- init_tellg = input.tellg();
- input >> got_d;
- got_ok = (input ? 1 : 0);
- input.clear();
- got_pos = input.tellg() - init_tellg;
- if (got_ok != want_ok)
- {
- WRONG ("stdc++ operator>> wrong status, check_mpf");
- cout << " want_ok: " << want_ok << "n";
- cout << " got_ok: " << got_ok << "n";
- }
- if (want_ok && want_d != got_d)
- {
- WRONG ("stdc++ operator>> wrong result, check_mpf");
- cout << " got: " << got_d << "n";
- cout << " want: " << want_d << "n";
- }
- if (putback_tellg_works && got_pos != want_pos)
- {
- WRONG ("stdc++ operator>> wrong position, check_mpf");
- cout << " want_pos: " << want_pos << "n";
- cout << " got_pos: " << got_pos << "n";
- }
- }
- {
- istringstream input (data[i].input);
- input.flags (data[i].flags);
- init_tellg = input.tellg();
- mpf_set_ui (got, 0xDEAD);
- input >> got;
- got_ok = (input ? 1 : 0);
- input.clear();
- got_pos = input.tellg() - init_tellg;
- if (got_ok != want_ok)
- {
- WRONG ("mpf operator>> wrong status");
- cout << " want_ok: " << want_ok << "n";
- cout << " got_ok: " << got_ok << "n";
- abort ();
- }
- if (want_ok && mpf_cmp (got, want) != 0)
- {
- WRONG ("mpf operator>> wrong result");
- mpf_trace (" got ", got);
- mpf_trace (" want", want);
- abort ();
- }
- if (putback_tellg_works && got_pos != want_pos)
- {
- WRONG ("mpf operator>> wrong position");
- cout << " want_pos: " << want_pos << "n";
- cout << " got_pos: " << got_pos << "n";
- abort ();
- }
- }
- }
- mpf_clear (got);
- mpf_clear (want);
- }
- int
- main (int argc, char *argv[])
- {
- if (argc > 1 && strcmp (argv[1], "-s") == 0)
- option_check_standard = 1;
- tests_start ();
- check_putback_tellg ();
- check_mpz ();
- check_mpq ();
- check_mpf ();
- tests_end ();
- return 0;
- }