/************************************************************************ * * 27.istream.fmat.arith.cpp - test exercising basic_istream * arithmetic extractors * * $Id: 27.istream.fmat.arith.cpp 648752 2008-04-16 17:01:56Z faridz $ * ************************************************************************ * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed * with this work for additional information regarding copyright * ownership. The ASF licenses this file to you under the Apache * License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or * implied. See the License for the specific language governing * permissions and limitations under the License. * **************************************************************************/ #include #include #include #include #include #include #include #include /***********************************************************************/ struct LocaleData { const char *whitespace; int decimal_point; int thousands_sep; const char *grouping; const char *truename; const char *falsename; }; template const std::locale make_locale (const CharT*, const LocaleData &data) { #if 255U == _RWSTD_UCHAR_MAX // work around a bogus gcc error: ISO C++ forbids variable-size // array (see https://issues.apache.org/jira/browse/STDCXX-351) static const std::size_t N = 256; #else // if UCHAR_MAX != 255 // determine the number of classic characters static const std::size_t N = std::ctype::table_size; #endif // derive a class so we can call the protected classic_table() struct ClassicTable: std::ctype { static const std::ctype_base::mask* get () { return classic_table (); } }; // get the classic C table of masks const std::ctype_base::mask* const classic = ClassicTable::get (); static int chars [N + 1]; static int masks [N + 1]; // -1 denotes end of characters (can't use 0 since it's a valid value) chars [N] = -1; // copy the classic table clearing the space bit of each mask for (std::size_t i = 0; i != N; ++i) { chars [i] = int (i); masks [i] = classic [i] & ~std::ctype_base::space; } typedef unsigned char UChar; // set the space bit for all characters in whitespace for (const char *ws = data.whitespace; *ws; ++ws) masks [UChar (*ws)] |= std::ctype_base::space; // create a user-defined ctype-derived facet and initialize // it with the character set and the specified masks const std::ctype* const ctp = new UserCtype(chars, masks); struct NumPunct: std::numpunct { // CharType typedef works around a Sun C++ bug stdcxx-345 typedef CharT CharType; typedef std::numpunct Base; typedef std::char_traits Traits; typedef std::allocator Allocator; typedef std::basic_string String; int dp_; int ts_; const char *grp_; const CharType *fn_; const CharType *tn_; NumPunct (int dp, int ts, const char *grp, const CharType *fn, const CharType *tn) : Base (), dp_ (dp), ts_ (ts), grp_ (grp ? grp : ""), fn_ (fn), tn_ (tn) { /* empty */ } CharType do_decimal_point () const { return -1 == dp_ ? Base::do_decimal_point () : make_char (char (dp_), (CharType*)0); } CharType do_thousands_sep () const { return -1 == ts_ ? Base::do_thousands_sep () : make_char (char (ts_), (CharType*)0); } std::string do_grouping () const { return 0 == grp_ ? Base::do_grouping () : std::string (grp_); } String do_truename () const { return 0 == tn_ ? Base::do_truename () : String (tn_); } String do_falsename () const { return 0 == fn_ ? Base::do_falsename () : String (fn_); } }; static CharT names [2][64]; names [false][0] = CharT (); names [true][0] = CharT (); if (data.falsename) { for (std::size_t i = 0; data.falsename [i]; ++i) { names [false][i] = data.falsename [i]; names [false][i + 1] = CharT (); } } if (data.truename) { for (std::size_t i = 0; data.truename [i]; ++i) { names [true][i] = data.truename [i]; names [true][i + 1] = CharT (); } } // create a user-defined numpunct-derived facet and initialize // its members with the specified parameters const std::numpunct* const np = new NumPunct (data.decimal_point, data.thousands_sep, data.grouping, data.falsename ? names [false] : 0, data.truename ? names [true] : 0); // install the new nupunct facet in a temporary locale, // replacing the original (if CharT=char or CharT=wchar_t) const std::locale tmp (std::locale::classic (), np); // install the new ctype facet in a locale, replacing // the original (if CharT=char or CharT=wchar_t) return std::locale (tmp, ctp); } /***********************************************************************/ template const std::locale make_locale (const CharT*, const Traits*, const LocaleData &data) { // construct a locale with the appropriate ctype and numpunct // facets installed const std::locale tmp (make_locale ((CharT*)0, data)); typedef std::istreambuf_iterator Iterator; typedef std::num_get NumGet; // check to see if num_get for this charater type and traits // is installed and install it if it isn't (i.e., when Traits // is other than std::char_traits) if (std::has_facet(tmp)) return tmp; return std::locale (tmp, new NumGet); } /***********************************************************************/ /* extern */ int opt_no_gcount; template void test_extractor (CharT*, Traits*, ArithmeticType*, const char *cname, const char *tname, const char *aname, int line, // printf formatting directive for ArithmeticType const char *valfmt, // character buffer (input sequence) const char *cbuf, // number of characters in buffer: std::size_t cbuf_size, // ctype and numpunct data const LocaleData &locale_data, // stream flags(): int flags, // initial stream rdstate(): int init_state, // unmasked exceptions: int exceptions, // expected exception: int expect_exception, // expected stream state after extraction: int expect_state, // expected number of extracted characters: int expect_extract, // have streambuf fail (or throw) after so many calls // to underflow() (each call extracts a single chracter): int fail_when, // initial value of the argument to extractor: ArithmeticType init_value, // expected value of the argument after extraction: ArithmeticType expect_value) { _RWSTD_UNUSED (cname); _RWSTD_UNUSED (tname); typedef std::basic_istream Istream; typedef MyStreambuf Streambuf; const char *fail_desc = 0; int fail_how = 0; if (fail_when < 0) { // have the stream buffer object's underflow() fail (by throwing // an exception if possible) after `fail_when' characters have // been extracted (this object calls underflow() for every char) fail_how = Underflow | Throw; fail_when = -fail_when; fail_desc = "threw"; } else if (0 < fail_when) { // have the stream buffer object's underflow() fail by returning // eof after `fail_when' characters have been extracted (this // object calls underflow() for every char) fail_how = Underflow; fail_desc = "returned EOF"; } // construct a stream buffer object and initialize its read sequence // with the character buffer Streambuf sb (cbuf, cbuf_size, fail_how, fail_when); // construct an istream object and initialize it with the user // defined streambuf object Istream is (&sb); if (-1 == flags) { // get the initial stream object's format control flags flags = is.flags (); } else { // set the stream object's format control flags is.flags (std::ios::fmtflags (flags)); } if (-1 == exceptions) { // get the initial stream object's exceptions exceptions = is.exceptions (); } else { // unmask the stream objects exceptions (must be done // before calling setstate() to prevent the latter from // throwing ios::failure) is.exceptions (std::ios::iostate (exceptions)); } if (-1 == init_state) { // get the initial stream object's state init_state = is.rdstate (); } else { // set the stream object's initial state #ifndef _RWSTD_NO_EXCEPTIONS try { is.setstate (std::ios::iostate (init_state)); } catch (...) { // ignore exceptions } #else // if defined ( _RWSTD_NO_EXCEPTIONS) is.setstate (std::ios::iostate (init_state)); #endif // _RWSTD_NO_EXCEPTIONS } // construct a locale object that treats only the specified `white' // characters as whitespace (all others are treated normally) const std::locale loc = is.imbue (make_locale ((CharT*)0, (Traits*)0, locale_data)); // imbue the previous locale into the stream buffer to verify that // the ws manipulator uses the locale imbued in the stream object // and not the one in the stream buffer sb.pubimbue (loc); // initialize the variable to the initial value to detect // the extractor setting it when it's not supposed to ArithmeticType value = init_value; // format the FUNCALL environment variable w/o writing out any output rw_fprintf (0, "%{$FUNCALL!:@}", "%{$CLASS}(%{*Ac}).operator>>(%s& = %{@}): " "initial flags() = %{If}, rdstate() = %{Is}, " "exceptions() = %{Is}, whitespace = %{#s}, numpunct = { " ".dp=%{#c}, .ts=%{#c}, .grp=%{#s}, .fn=%{#s}, .tn=%{#s} }", int (sizeof *cbuf), cbuf, aname, valfmt, init_value, flags, init_state, exceptions, locale_data.whitespace, locale_data.decimal_point, locale_data.thousands_sep, locale_data.grouping, locale_data.falsename, locale_data.truename); #ifndef _RWSTD_NO_EXCEPTIONS int caught = 0; try { is >> value; } catch (Exception&) { caught = 1; } catch (std::ios_base::failure &ex) { caught = 2; rw_assert (caught == expect_exception, 0, line, "line %d. %{$FUNCALL}: unexpectedly threw " "ios_base::failure(%{#s})", __LINE__, ex.what ()); } catch (...) { caught = -1; rw_assert (false, 0, line, "line %d. %{$FUNCALL}: unexpectely threw an exception " "of unknown type", __LINE__); } ////////////////////////////////////////////////////////////////// // verify that the function propagates exceptions thrown from the // streambuf object only when badbit is set in the stream object's // exceptions() rw_assert (caught == expect_exception, 0, line, "line %d. %{$FUNCALL}: " "%{?}failed to throw" "%{:}unexpectedly propagated" "%{;} exception", __LINE__, expect_exception); #else // if defined (_RWSTD_NO_EXCEPTIONS) is >> value; #endif // _RWSTD_NO_EXCEPTIONS // clear the text describing the type of failure when streambuf // didn't actually fail (or throw) if (sb.failed_ == None && sb.threw_ == None) fail_desc = 0; ////////////////////////////////////////////////////////////////// // verify that the expected number of characters have been // extracted from the stream const int extracted = int (sb.pubgptr () - sb.pubeback ()); rw_assert (expect_extract == extracted, 0, line, "%d. %{$FUNCALL}: expected to extract %d characters, " "got %d%{?} (underflow() %s at extraction %u)%{;}", __LINE__, expect_extract, extracted, 0 != fail_desc, fail_desc, fail_when); ////////////////////////////////////////////////////////////////// // verify that gcount() is not affected if (0 == opt_no_gcount) rw_assert (0 == is.gcount (), 0, line, "%d. %{$FUNCALL}: gcount() == 0, got %d " "%{?} (underflow() %s at extraction %u)%{;}", __LINE__, is.gcount (), 0 != fail_desc, fail_desc, fail_when); ////////////////////////////////////////////////////////////////// // verify the state of the stream object after the function call rw_assert (is.rdstate () == expect_state, 0, line, "line %d. %{$FUNCALL}: rdstate() == %{Is}, got %{Is}" "%{?} (underflow() %s at extraction %u)%{;}", __LINE__, expect_state, is.rdstate(), 0 != fail_desc, fail_desc, fail_when); ////////////////////////////////////////////////////////////////// // verify the extracted value matches the expected value rw_assert (expect_value == value, 0, line, "line %d. %{$FUNCALL}: expected value %{@}, got %{@}", __LINE__, valfmt, expect_value, valfmt, value); } /***********************************************************************/ // state abbreviations for brevity const int ___ = 0; const int __f = 0 | 0 | std::ios::failbit; const int _e_ = 0 | std::ios::eofbit | 0; const int _ef = 0 | std::ios::eofbit | std::ios::failbit; const int b__ = std::ios::badbit | 0 | 0; const int b_f = std::ios::badbit | 0 | std::ios::failbit; const int be_ = std::ios::badbit | std::ios::eofbit | 0; const int bef = std::ios::badbit | std::ios::eofbit | std::ios::failbit; const int DEC = std::ios::dec; const int OCT = std::ios::oct; const int HEX = std::ios::hex; template void test_extractor (CharT*, Traits*, ArithmeticType*, const char *cname, const char *tname, const char *aname, const char *fmt) { typedef ArithmeticType T; LocaleData locale_data = { 0, -1, -1, 0, 0, 0 }; static const volatile T zero = T (); static const volatile T negative_one = T (-1); const bool is_signed = negative_one < zero; const bool is_floating = zero > negative_one / 2; // avoid test cases designed to exercise the extraction of negative // values when ArithmeticType is an unsigned type #undef TEST #define TEST(str, fl, is, ex, ee, es, ne, fw, iv, ev) \ if (is_signed || 0 <= ev) \ test_extractor ((CharT*)0, (Traits*)0, (T*)0, cname, tname, aname, \ __LINE__, fmt, str, sizeof str - 1, locale_data, \ fl, is, ex, ee, es, ne, fw, (T)(iv), (T)ev) locale_data.whitespace = ""; // +-- subject sequence // | +-- initial flags (-1 for default) // | | +-- initial state (-1 for default) // | | | +-- exceptions (-1 for default) // | | | | +-- expected exception // | | | | | +-- expected rdstate() // | | | | | | +-- extracted characters // | | | | | | | +-- fail when? (0 to not) // | | | | | | | | +-- initial value // | | | | | | | | | +-- expected value // | | | | | | | | | | // V V V V V V V V V V TEST ("", -1, -1, -1, 0, _ef, 0, 0, 1, 1); TEST (" ", -1, -1, -1, 0, __f, 0, 0, 2, 2); TEST (" ", -1, -1, -1, 0, _ef, 0, 1, 3, 3); // fail TEST (" ", -1, -1, -1, 0, b__, 0, -1, 4, 4); // throw // exercise behavior when the initial state is other than good TEST (" ", -1, __f, -1, 0, __f, 0, -1, 5, 5); TEST (" ", -1, _e_, -1, 0, _ef, 0, -1, 6, 6); TEST (" ", -1, _ef, -1, 0, _ef, 0, -1, 7, 7); TEST (" ", -1, b__, -1, 0, b_f, 0, -1, 8, 8); TEST (" ", -1, b_f, -1, 0, b_f, 0, -1, 9, 9); TEST (" ", -1, be_, -1, 0, bef, 0, -1, 10, 10); TEST (" ", -1, bef, -1, 0, bef, 0, -1, 11, 11); // verify that when the initial state isn't good the extractors // do not attempt to obtain the requested input but call setstate() // to set failbit (which causes failure to be thrown when failbit // or any other bit is set in exceptions) (see LWG issue 419) TEST (" ", -1, __f, __f, 2, __f, 0, -1, 9, 9); TEST (" ", -1, _e_, __f, 2, _ef, 0, -1, 9, 9); TEST (" ", -1, _e_, _e_, 2, _ef, 0, -1, 9, 9); TEST (" ", -1, _ef, _e_, 2, _ef, 0, -1, 9, 9); TEST (" ", -1, b__, __f, 2, b_f, 0, -1, 9, 9); TEST (" ", -1, b_f, __f, 2, b_f, 0, -1, 9, 9); TEST (" ", -1, b_f, b__, 2, b_f, 0, -1, 9, 9); locale_data.whitespace = " "; TEST (" ", -1, -1, -1, 0, _ef, 1, 0, 9, 9); TEST (" ", -1, -1, -1, 0, _ef, 0, 1, 9, 9); // fail TEST (" ", -1, -1, -1, 0, b__, 0, -1, 9, 9); // throw TEST (" ", -1, -1, -1, 0, _ef, 1, 2, 9, 9); // fail TEST (" ", -1, -1, -1, 0, b__, 1, -2, 9, 9); // throw TEST ("_", -1, -1, -1, 0, __f, 0, 0, 9, 9); TEST (" ", 0, -1, -1, 0, __f, 0, 0, 9, 9); locale_data.whitespace = "_"; TEST (" ", -1, -1, -1, 0, __f, 0, 0, 9, 9); TEST ("_", -1, -1, -1, 0, _ef, 1, 0, 9, 9); locale_data.whitespace = ""; TEST ("0", -1, -1, -1, 0, _e_, 1, 0, 9, 0); TEST ("1", -1, -1, -1, 0, _e_, 1, 0, 9, 1); TEST ("+0", -1, -1, -1, 0, _e_, 2, 0, 9, 0); TEST ("-0", -1, -1, -1, 0, _e_, 2, 0, 9, 0); TEST ("+1", -1, -1, -1, 0, _e_, 2, 0, 9, 1); TEST ("-1", -1, -1, -1, 0, _e_, 2, 0, 1, -1); TEST ("+2 ", -1, -1, -1, 0, ___, 2, 0, 9, 2); TEST ("-2 ", -1, -1, -1, 0, ___, 2, 0, 9, -2); if (is_floating) { TEST ("3.", -1, -1, -1, 0, _e_, 2, 0, 9, 3); TEST ("+3.", -1, -1, -1, 0, _e_, 3, 0, 9, 3); TEST ("-3.", -1, -1, -1, 0, _e_, 3, 0, 9, -3); } else { TEST ("3.", -1, -1, -1, 0, ___, 1, 0, 9, 3); TEST ("+3.", -1, -1, -1, 0, ___, 2, 0, 9, 3); TEST ("-3.", -1, -1, -1, 0, ___, 2, 0, 9, -3); } // set '#' as the only whitespace character locale_data.whitespace = "#"; TEST ("#+3", -1, -1, -1, 0, _e_, 3, 0, 9, 3); TEST ("#-4", -1, -1, -1, 0, _e_, 3, 0, 9, -4); TEST ("#+5", -1, -1, -1, 0, _e_, 3, 0, 9, 5); TEST ("#-6", -1, -1, -1, 0, _e_, 3, 0, 9, -6); TEST ("#+7#", -1, -1, -1, 0, ___, 3, 0, 9, 7); TEST ("#-8#", -1, -1, -1, 0, ___, 3, 0, 9, -8); TEST (" -9", -1, -1, -1, 0, __f, 0, 0, -9, -9); // set 'X', 'Y', and 'Z' as the only whitespace characters locale_data.whitespace = "XYZ"; TEST ("X10", -1, -1, -1, 0, _e_, 3, 0, 9, 10); TEST ("XY11", -1, -1, -1, 0, _e_, 4, 0, 9, 11); TEST ("XYZ12", -1, -1, -1, 0, _e_, 5, 0, 9, 12); // set '9' as the whitespace character locale_data.whitespace = "9"; TEST ("9", -1, -1, -1, 0, _ef, 1, 0, 8, 8); TEST ("99", -1, -1, -1, 0, _ef, 2, 0, 8, 8); TEST ("999", -1, -1, -1, 0, _ef, 3, 0, 8, 8); TEST ("9991", -1, -1, -1, 0, _e_, 4, 0, 8, 1); // exercise grouping locale_data.whitespace = "_"; locale_data.thousands_sep = ';'; locale_data.grouping = "\1"; TEST ("0;0", -1, -1, -1, 0, _e_, 3, 0, 9, 0); TEST ("+0;0", -1, -1, -1, 0, _e_, 4, 0, 9, 0); TEST ("-0;0", -1, -1, -1, 0, _e_, 4, 0, 9, 0); TEST ("+0;1", -1, -1, -1, 0, _e_, 4, 0, 9, 1); TEST ("-0;1", -1, -1, -1, 0, _e_, 4, 0, 9, -1); TEST ("0;1", -1, -1, -1, 0, _e_, 3, 0, 9, 1); TEST ("1;0", -1, -1, -1, 0, _e_, 3, 0, 9, 10); TEST ("1;2", -1, -1, -1, 0, _e_, 3, 0, 9, 12); TEST ("_1;2", -1, -1, -1, 0, _e_, 4, 0, 9, 12); TEST ("_1;2_", -1, -1, -1, 0, ___, 4, 0, 9, 12); TEST ("_1_;2", -1, -1, -1, 0, ___, 2, 0, 9, 1); TEST ("12345", -1, -1, -1, 0, _e_, 5, 0, 9, 12345); TEST ("1;2;3;4;5", -1, -1, -1, 0, _e_, 9, 0, 9, 12345); TEST ("12;3;4;5", -1, -1, -1, 0, _ef, 8, 0, 9, 12345); // exercise thousands_sep that's a space locale_data.whitespace = " "; locale_data.thousands_sep = ' '; locale_data.grouping = "\2"; TEST (" 0", -1, -1, -1, 0, _e_, 2, 0, 9, 0); TEST (" 0", -1, -1, -1, 0, _e_, 3, 0, 9, 0); TEST (" 0", -1, -1, -1, 0, _e_, 4, 0, 9, 0); TEST (" 0 00", -1, -1, -1, 0, _e_, 5, 0, 9, 0); TEST ("+0 00", -1, -1, -1, 0, _e_, 5, 0, 9, 0); TEST ("-0 00", -1, -1, -1, 0, _e_, 5, 0, 9, 0); TEST (" +0 00", -1, -1, -1, 0, _e_, 6, 0, 9, 0); TEST (" -0 00", -1, -1, -1, 0, _e_, 6, 0, 9, 0); TEST (" +0 00", -1, -1, -1, 0, _e_, 7, 0, 9, 0); TEST (" -0 00", -1, -1, -1, 0, _e_, 7, 0, 9, 0); TEST (" +00 00", -1, -1, -1, 0, _e_, 7, 0, 9, 0); TEST (" -00 00", -1, -1, -1, 0, _e_, 7, 0, 9, 0); TEST (" 00 01", -1, -1, -1, 0, _e_, 7, 0, 9, 1); TEST (" +00 01", -1, -1, -1, 0, _e_, 7, 0, 9, 1); TEST (" -00 01", -1, -1, -1, 0, _e_, 7, 0, 1, -1); TEST ("0 01 02", -1, -1, -1, 0, _e_, 7, 0, 9, 102); TEST ("1 02 03", -1, -1, -1, 0, _e_, 7, 0, 9, 10203); TEST ("2 03 04", -1, -1, -1, 0, _e_, 7, 0, 9, 20304); TEST ("304 05", -1, -1, -1, 0, _ef, 6, 0, 9, 30405); TEST ("4 0 5 0", -1, -1, -1, 0, _ef, 7, 0, 9, 4050); // according to the grammar in locale.numpunct, a valid number // cannot start or end with a thousands separator (and all pairs // of thousands separator must be separated by at least one // digit) locale_data.whitespace = "_"; locale_data.thousands_sep = ';'; locale_data.grouping = "\1"; TEST (";", -1, -1, -1, 0, __f, 0, 0, 9, 9); TEST (";;", -1, -1, -1, 0, __f, 0, 0, 9, 9); TEST ("_;", -1, -1, -1, 0, __f, 1, 0, 9, 9); TEST ("+;", -1, -1, -1, 0, __f, 1, 0, 9, 9); TEST ("-;", -1, -1, -1, 0, __f, 1, 0, 9, 9); TEST ("0;", -1, -1, -1, 0, _ef, 2, 0, 9, 9); TEST ("+0;", -1, -1, -1, 0, _ef, 3, 0, 9, 9); TEST ("-0;", -1, -1, -1, 0, _ef, 3, 0, 9, 9); TEST ("+1;", -1, -1, -1, 0, _ef, 3, 0, 9, 9); TEST ("-1;", -1, -1, -1, 0, _ef, 3, 0, 9, 9); TEST ("1;", -1, -1, -1, 0, _ef, 2, 0, 9, 9); TEST ("0;_", -1, -1, -1, 0, __f, 2, 0, 9, 9); TEST ("1;_", -1, -1, -1, 0, __f, 2, 0, 9, 9); TEST ("_0;", -1, -1, -1, 0, _ef, 3, 0, 9, 9); TEST ("_1;", -1, -1, -1, 0, _ef, 3, 0, 9, 9); TEST ("0;;", -1, -1, -1, 0, __f, 2, 0, 9, 9); TEST ("1;;", -1, -1, -1, 0, __f, 2, 0, 9, 9); TEST (";0", -1, -1, -1, 0, __f, 0, 0, 9, 9); TEST (";1", -1, -1, -1, 0, __f, 0, 0, 9, 9); TEST ("_;0", -1, -1, -1, 0, __f, 1, 0, 9, 9); TEST ("_;1", -1, -1, -1, 0, __f, 1, 0, 9, 9); // exercise errors when thousands_sep that's a space locale_data.whitespace = " "; locale_data.thousands_sep = ' '; locale_data.grouping = "\2"; TEST (" ", -1, -1, -1, 0, _ef, 1, 0, 9, 9); TEST (" +", -1, -1, -1, 0, _ef, 2, 0, 9, 9); TEST (" -", -1, -1, -1, 0, _ef, 2, 0, 9, 9); TEST (" + ", -1, -1, -1, 0, __f, 2, 0, 9, 9); TEST (" - ", -1, -1, -1, 0, __f, 2, 0, 9, 9); TEST (" 0 ", -1, -1, -1, 0, _ef, 3, 0, 9, 9); TEST (" +0 ", -1, -1, -1, 0, _ef, 4, 0, 9, 9); TEST (" -0 ", -1, -1, -1, 0, _ef, 4, 0, 9, 9); TEST (" 123 ", -1, -1, -1, 0, _ef, 5, 0, 9, 9); TEST (" +123 ", -1, -1, -1, 0, _ef, 6, 0, 9, 9); TEST (" -123 ", -1, -1, -1, 0, _ef, 6, 0, 9, 9); } /***********************************************************************/ void info (const char *cname, const char *tname, const char *type) { // format the CLASS environment variable w/o writing out any output rw_fprintf (0, "%{$CLASS!:@}", "%{?}istream%{:}%{?}wistream" "%{:}basic_istream<%s, %s>%{;}%{;}", 'c' == *cname && 's' == *tname, 'w' == *cname && 's' == *tname, cname, tname); rw_info (0, 0, __LINE__, "std::%{$CLASS}::operator>>(%s&)", type); } /***********************************************************************/ #undef TEST #define TEST(T, fmt, str, fl, is, ex, ee, es, ne, fw, iv, ev) \ test_extractor ((CharT*)0, (Traits*)0, (T*)0, cname, tname, #T, \ __LINE__, fmt, str, sizeof str - 1, locale_data, \ fl, is, ex, ee, es, ne, fw, (T)(iv), (T)ev) /***********************************************************************/ template void test_bool (CharT*, Traits*, const char *cname, const char *tname) { info (cname, tname, "bool"); #define TEST_BOOL(ss, fl, is, ex, ee, es, ne, fw, iv, ev) \ TEST (bool, "%b", ss, fl, is, ex, ee, es, ne, fw, iv, ev) const int ba = std::ios::boolalpha; const int ba_ws = ba | std::ios::skipws; LocaleData locale_data = { 0, -1, -1, 0, 0, 0 }; locale_data.whitespace = "_"; locale_data.falsename = "NO"; locale_data.truename = "YES"; TEST_BOOL ("", -1, -1, -1, 0, _ef, 0, 0, false, false); TEST_BOOL ("", -1, -1, -1, 0, _ef, 0, 0, true, true); TEST_BOOL ("0", -1, -1, -1, 0, _e_, 1, 0, true, false); TEST_BOOL ("1", -1, -1, -1, 0, _e_, 1, 0, false, true); TEST_BOOL ("+0", -1, -1, -1, 0, _e_, 2, 0, true, false); TEST_BOOL ("-0", -1, -1, -1, 0, _e_, 2, 0, true, false); TEST_BOOL ("+1", -1, -1, -1, 0, _e_, 2, 0, false, true); TEST_BOOL ("00", -1, -1, -1, 0, _e_, 2, 0, true, false); TEST_BOOL ("01", -1, -1, -1, 0, _e_, 2, 0, false, true); TEST_BOOL ("_000", -1, -1, -1, 0, _e_, 4, 0, true, false); TEST_BOOL ("_001", -1, -1, -1, 0, _e_, 4, 0, false, true); TEST_BOOL ("NO", -1, -1, -1, 0, __f, 0, 0, true, true); TEST_BOOL ("YES", -1, -1, -1, 0, __f, 0, 0, false, false); TEST_BOOL ("_NO", -1, -1, -1, 0, __f, 1, 0, true, true); TEST_BOOL ("_YES", -1, -1, -1, 0, __f, 1, 0, false, false); TEST_BOOL ("NO", ba, -1, -1, 0, ___, 2, 0, false, false); TEST_BOOL ("YES", ba, -1, -1, 0, ___, 3, 0, true, true); TEST_BOOL ("_NO", ba_ws, -1, -1, 0, ___, 3, 0, false, false); TEST_BOOL ("_YES", ba_ws, -1, -1, 0, ___, 4, 0, true, true); TEST_BOOL ("_NO_", ba_ws, -1, -1, 0, ___, 3, 0, false, false); TEST_BOOL ("_YES_", ba_ws, -1, -1, 0, ___, 4, 0, true, true); locale_data.falsename = "bool:0"; locale_data.truename = "bool:1"; TEST_BOOL ("bool:0", ba, -1, -1, 0, ___, 6, 0, false, false); TEST_BOOL ("bool:1", ba, -1, -1, 0, ___, 6, 0, true, true); TEST_BOOL ("bool:2", ba, -1, -1, 0, __f, 5, 0, true, true); } /***********************************************************************/ template void test_shrt (CharT*, Traits*, const char *cname, const char *tname) { info (cname, tname, "short"); test_extractor ((CharT*)0, (Traits*)0, (short*)0, cname, tname, "short", "%hi"); #define TEST_SHRT(ss, fl, is, ex, ee, es, ne, fw, iv, ev) \ TEST (short, "%hi", ss, fl, is, ex, ee, es, ne, fw, iv, ev) LocaleData locale_data = { 0, -1, -1, 0, 0, 0 }; locale_data.whitespace = ""; #if 2 == _RWSTD_SHRT_SIZE const short smax = +32767; const short smin = -smax - 1; TEST_SHRT ("-32768", -1, -1, -1, 0, _e_, 6, 0, -1, smin); TEST_SHRT ("-32769", -1, -1, -1, 0, _ef, 6, 0, -1, smin); TEST_SHRT ("-99999", -1, -1, -1, 0, _ef, 6, 0, -1, smin); TEST_SHRT ("+32767", -1, -1, -1, 0, _e_, 6, 0, -1, smax); TEST_SHRT ("+32768", -1, -1, -1, 0, _ef, 6, 0, -1, smax); TEST_SHRT ("+99999", -1, -1, -1, 0, _ef, 6, 0, -1, smax); TEST_SHRT ("999999", -1, -1, -1, 0, _ef, 6, 0, -1, smax); #elif 4 == _RWSTD_SHRT_SIZE const short smax = +2147483647; const short smin = -smax - 1; TEST_SHRT ("-2147483648", -1, -1, -1, 0, _e_, 11, 0, -1, smin); TEST_SHRT ("-2147483649", -1, -1, -1, 0, _ef, 11, 0, -1, smin); TEST_SHRT ("-9999999999", -1, -1, -1, 0, _ef, 11, 0, -1, smin); TEST_SHRT ("+2147483647", -1, -1, -1, 0, _e_, 11, 0, -1, smax); TEST_SHRT ("+2147483648", -1, -1, -1, 0, _ef, 11, 0, -1, smax); TEST_SHRT ("+9999999999", -1, -1, -1, 0, _ef, 11, 0, -1, smax); TEST_SHRT ("99999999999", -1, -1, -1, 0, _ef, 11, 0, -1, smax); #endif // _RWSTD_SHRT_SIZE } /***********************************************************************/ template void test_ushrt (CharT*, Traits*, const char *cname, const char *tname) { info (cname, tname, "unsigned short"); test_extractor ((CharT*)0, (Traits*)0, (unsigned short*)0, cname, tname, "unsigned short", "%hu"); #define TEST_USHRT(ss, fl, is, ex, ee, es, ne, fw, iv, ev) \ TEST (unsigned short, "%hu", ss, fl, is, ex, ee, es, ne, fw, iv, ev) LocaleData locale_data = { 0, -1, -1, 0, 0, 0 }; locale_data.whitespace = ""; #if 2 == _RWSTD_USHRT_SIZE const unsigned short usmax = 65535U; TEST_SHRT ("65535", -1, -1, -1, 0, _e_, 5, 0, 1, usmax); TEST_SHRT ("65536", -1, -1, -1, 0, _ef, 5, 0, 1, usmax); TEST_SHRT ("99999", -1, -1, -1, 0, _ef, 5, 0, 1, usmax); #elif 4 == _RWSTD_USHRT_SIZE const unsigned short usmax = 4294967295U; TEST_SHRT ("4294967295", -1, -1, -1, 0, _e_, 10, 0, -1, usmax); TEST_SHRT ("4294967296", -1, -1, -1, 0, _ef, 10, 0, -1, usmax); TEST_SHRT ("9999999999", -1, -1, -1, 0, _ef, 10, 0, -1, usmax); #endif // _RWSTD_USHRT_SIZE } /***********************************************************************/ template void test_int (CharT*, Traits*, const char *cname, const char *tname) { info (cname, tname, "int"); test_extractor ((CharT*)0, (Traits*)0, (int*)0, cname, tname, "int", "%i"); #define TEST_INT(ss, fl, is, ex, ee, es, ne, fw, iv, ev) \ TEST (int, "%i", ss, fl, is, ex, ee, es, ne, fw, iv, ev) LocaleData locale_data = { 0, -1, -1, 0, 0, 0 }; locale_data.whitespace = ""; #if 2 == _RWSTD_INT_SIZE const int imax = +32767; const int imin = -imax - 1; TEST_INT ("-32768", -1, -1, -1, 0, _e_, 6, 0, 1, imin); TEST_INT ("-32769", -1, -1, -1, 0, _ef, 6, 0, 1, imin); TEST_INT ("-99999", -1, -1, -1, 0, _ef, 6, 0, 1, imin); TEST_INT ("+32767", -1, -1, -1, 0, _e_, 6, 0, 1, imax); TEST_INT ("+32768", -1, -1, -1, 0, _ef, 6, 0, 1, imax); TEST_INT ("+99999", -1, -1, -1, 0, _ef, 6, 0, 1, imax); #elif 4 == _RWSTD_INT_SIZE const int imax = +2147483647; const int imin = -imax - 1; TEST_INT ("-2147483648", -1, -1, -1, 0, _e_, 11, 0, -1, imin); TEST_INT ("-2147483649", -1, -1, -1, 0, _ef, 11, 0, -1, imin); TEST_INT ("-9999999999", -1, -1, -1, 0, _ef, 11, 0, -1, imin); TEST_INT ("+2147483647", -1, -1, -1, 0, _e_, 11, 0, -1, imax); TEST_INT ("+2147483648", -1, -1, -1, 0, _ef, 11, 0, -1, imax); TEST_INT ("99999999999", -1, -1, -1, 0, _ef, 11, 0, -1, imax); #elif 8 == _RWSTD_INT_SIZE const int imax = +9223372036854775807; const int imin = -imax - 1; TEST_INT ("-9223372036854775808", -1, -1, -1, 0, _e_, 20, 0, -1, imin); TEST_INT ("-9223372036854775809", -1, -1, -1, 0, _ef, 20, 0, -1, imin); TEST_INT ("-9999999999999999999", -1, -1, -1, 0, _ef, 20, 0, -1, imin); TEST_INT ("+9223372036854775807", -1, -1, -1, 0, _e_, 20, 0, -1, imax); TEST_INT ("+9223372036854775808", -1, -1, -1, 0, _ef, 20, 0, -1, imax); TEST_INT ("99999999999999999999", -1, -1, -1, 0, _ef, 20, 0, -1, imax); #endif // _RWSTD_INT_SIZE } /***********************************************************************/ template void test_uint (CharT*, Traits*, const char *cname, const char *tname) { info (cname, tname, "unsigned int"); test_extractor ((CharT*)0, (Traits*)0, (unsigned int*)0, cname, tname, "unsigned int", "%u"); #define TEST_UINT(ss, fl, is, ex, ee, es, ne, fw, iv, ev) \ TEST (int, "%u", ss, fl, is, ex, ee, es, ne, fw, iv, ev) LocaleData locale_data = { 0, -1, -1, 0, 0, 0 }; locale_data.whitespace = ""; #if 2 == _RWSTD_UINT_SIZE const unsigned uimax = 65535U; TEST_INT ("65535", -1, -1, -1, 0, _e_, 5, 0, 1, uimax); TEST_INT ("65536", -1, -1, -1, 0, _ef, 5, 0, 1, uimax); TEST_INT ("99999", -1, -1, -1, 0, _ef, 5, 0, 1, uimax); #elif 4 == _RWSTD_UINT_SIZE const unsigned uimax = 4294967295U; TEST_INT ("4294967295", -1, -1, -1, 0, _e_, 10, 0, -1, uimax); TEST_INT ("4294967296", -1, -1, -1, 0, _ef, 10, 0, -1, uimax); TEST_INT ("9999999999", -1, -1, -1, 0, _ef, 10, 0, -1, uimax); #elif 8 == _RWSTD_UINT_SIZE const unsigned uimax = 9223372036854775807U; TEST_INT ("9223372036854775807", -1, -1, -1, 0, _e_, 10, 0, -1, uimax); TEST_INT ("9223372036854775808", -1, -1, -1, 0, _ef, 10, 0, -1, uimax); TEST_INT ("9999999999999999999", -1, -1, -1, 0, _ef, 10, 0, -1, uimax); #endif // _RWSTD_UINT_SIZE } /***********************************************************************/ template void test_long (CharT*, Traits*, const char *cname, const char *tname) { info (cname, tname, "long"); test_extractor ((CharT*)0, (Traits*)0, (long*)0, cname, tname, "long", "%li"); #define TEST_LONG(ss, fl, is, ex, ee, es, ne, fw, iv, ev) \ TEST (long, "%li", ss, fl, is, ex, ee, es, ne, fw, iv, ev) LocaleData locale_data = { 0, -1, -1, 0, 0, 0 }; locale_data.whitespace = ""; #if 2 == _RWSTD_LONG_SIZE const long lmax = +32767L; const long lmin = -lmax - 1; TEST_LONG ("-32768", -1, -1, -1, 0, _e_, 6, 0, 1, lmin); TEST_LONG ("-32769", -1, -1, -1, 0, _ef, 6, 0, 1, lmin); TEST_LONG ("-99999", -1, -1, -1, 0, _ef, 6, 0, 1, lmin); TEST_LONG ("+32767", -1, -1, -1, 0, _e_, 6, 0, 1, lmax); TEST_LONG ("+32768", -1, -1, -1, 0, _ef, 6, 0, 1, lmax); TEST_LONG ("+99999", -1, -1, -1, 0, _ef, 6, 0, 1, lmax); #elif 4 == _RWSTD_LONG_SIZE const long lmax = +2147483647L; const long lmin = -lmax - 1; TEST_LONG ("-2147483648", -1, -1, -1, 0, _e_, 11, 0, -1, lmin); TEST_LONG ("-2147483649", -1, -1, -1, 0, _ef, 11, 0, -1, lmin); TEST_LONG ("-9999999999", -1, -1, -1, 0, _ef, 11, 0, -1, lmin); TEST_LONG ("+2147483647", -1, -1, -1, 0, _e_, 11, 0, -1, lmax); TEST_LONG ("+2147483648", -1, -1, -1, 0, _ef, 11, 0, -1, lmax); TEST_LONG ("99999999999", -1, -1, -1, 0, _ef, 11, 0, -1, lmax); #elif 8 == _RWSTD_LONG_SIZE const long lmax = +9223372036854775807L; const long lmin = -lmax - 1; TEST_LONG ("-9223372036854775808", -1, -1, -1, 0, _e_, 20, 0, -1, lmin); TEST_LONG ("-9223372036854775809", -1, -1, -1, 0, _ef, 20, 0, -1, lmin); TEST_LONG ("-9999999999999999999", -1, -1, -1, 0, _ef, 20, 0, -1, lmin); TEST_LONG ("+9223372036854775807", -1, -1, -1, 0, _e_, 20, 0, -1, lmax); TEST_LONG ("+9223372036854775808", -1, -1, -1, 0, _ef, 20, 0, -1, lmax); TEST_LONG ("99999999999999999999", -1, -1, -1, 0, _ef, 20, 0, -1, lmax); #endif // _RWSTD_LONG_SIZE } /***********************************************************************/ template void test_ulong (CharT*, Traits*, const char *cname, const char *tname) { info (cname, tname, "unsigned long"); test_extractor ((CharT*)0, (Traits*)0, (unsigned long*)0, cname, tname, "unsigned long", "%lu"); #define TEST_ULONG(ss, fl, is, ex, ee, es, ne, fw, iv, ev) \ TEST (unsigned long, "%lu", ss, fl, is, ex, ee, es, ne, fw, iv, ev) LocaleData locale_data = { 0, -1, -1, 0, 0, 0 }; locale_data.whitespace = ""; #if 2 == _RWSTD_ULONG_SIZE const unsigned ulmax = 65535UL; TEST_ULONG ("65535", -1, -1, -1, 0, _e_, 5, 0, 1, ulmax); TEST_ULONG ("65536", -1, -1, -1, 0, _ef, 5, 0, 1, ulmax); TEST_ULONG ("99999", -1, -1, -1, 0, _ef, 5, 0, 1, ulmax); #elif 4 == _RWSTD_ULONG_SIZE const unsigned ulmax = 4294967295UL; TEST_ULONG ("4294967295", -1, -1, -1, 0, _e_, 10, 0, -1, ulmax); TEST_ULONG ("4294967296", -1, -1, -1, 0, _ef, 10, 0, -1, ulmax); TEST_ULONG ("9999999999", -1, -1, -1, 0, _ef, 10, 0, -1, ulmax); #elif 8 == _RWSTD_ULONG_SIZE const unsigned ulmax = 9223372036854775807UL; TEST_ULONG ("9223372036854775807", -1, -1, -1, 0, _e_, 10, 0, -1, ulmax); TEST_ULONG ("9223372036854775808", -1, -1, -1, 0, _ef, 10, 0, -1, ulmax); TEST_ULONG ("9999999999999999999", -1, -1, -1, 0, _ef, 10, 0, -1, ulmax); #endif // _RWSTD_ULONG_SIZE } /***********************************************************************/ template void test_llong (CharT*, Traits*, const char *cname, const char *tname) { info (cname, tname, "long long"); test_extractor ((CharT*)0, (Traits*)0, (long long*)0, cname, tname, "long long", "%lli"); #define TEST_LLONG(ss, fl, is, ex, ee, es, ne, fw, iv, ev) \ TEST (long long, "%lli", ss, fl, is, ex, ee, es, ne, fw, iv, ev) LocaleData locale_data = { 0, -1, -1, 0, 0, 0 }; locale_data.whitespace = ""; #if 2 == _RWSTD_LLONG_SIZE const long long llmax = +32767LL; const long long llmin = -llmax - 1; TEST_LLONG ("-32768", -1, -1, -1, 0, _e_, 6, 0, 1, llmin); TEST_LLONG ("-32769", -1, -1, -1, 0, _ef, 6, 0, 1, llmin); TEST_LLONG ("-99999", -1, -1, -1, 0, _ef, 6, 0, 1, llmin); TEST_LLONG ("+32767", -1, -1, -1, 0, _e_, 6, 0, 1, llmax); TEST_LLONG ("+32768", -1, -1, -1, 0, _ef, 6, 0, 1, llmax); TEST_LLONG ("+99999", -1, -1, -1, 0, _ef, 6, 0, 1, llmax); #elif 4 == _RWSTD_LLONG_SIZE const long long llmax = +2147483647LL; const long long llmin = -llmax - 1; TEST_LLONG ("-2147483648", -1, -1, -1, 0, _e_, 11, 0, -1, llmin); TEST_LLONG ("-2147483649", -1, -1, -1, 0, _ef, 11, 0, -1, llmin); TEST_LLONG ("-9999999999", -1, -1, -1, 0, _ef, 11, 0, -1, llmin); TEST_LLONG ("+2147483647", -1, -1, -1, 0, _e_, 11, 0, -1, llmax); TEST_LLONG ("+2147483648", -1, -1, -1, 0, _ef, 11, 0, -1, llmax); TEST_LLONG ("99999999999", -1, -1, -1, 0, _ef, 11, 0, -1, llmax); #elif 8 == _RWSTD_LLONG_SIZE const long long llmax = +9223372036854775807LL; const long long llmin = -llmax - 1; TEST_LLONG ("-9223372036854775808", -1, -1, -1, 0, _e_, 20, 0, -1, llmin); TEST_LLONG ("-9223372036854775809", -1, -1, -1, 0, _ef, 20, 0, -1, llmin); TEST_LLONG ("-9999999999999999999", -1, -1, -1, 0, _ef, 20, 0, -1, llmin); TEST_LLONG ("+9223372036854775807", -1, -1, -1, 0, _e_, 20, 0, -1, llmax); TEST_LLONG ("+9223372036854775808", -1, -1, -1, 0, _ef, 20, 0, -1, llmax); TEST_LLONG ("99999999999999999999", -1, -1, -1, 0, _ef, 20, 0, -1, llmax); #endif // _RWSTD_LLONG_SIZE } /***********************************************************************/ template void test_ullong (CharT*, Traits*, const char *cname, const char *tname) { info (cname, tname, "unsigned long long"); test_extractor ((CharT*)0, (Traits*)0, (unsigned long long*)0, cname, tname, "unsigned long long", "%llu"); #define TEST_ULLONG(ss, fl, is, ex, ee, es, ne, fw, iv, ev) \ TEST (unsigned long long, "%llu", ss, fl, is, ex, ee, es, ne, fw, iv, ev) LocaleData locale_data = { 0, -1, -1, 0, 0, 0 }; locale_data.whitespace = ""; #if 2 == _RWSTD_ULLONG_SIZE const unsigned long long ullmax = 65535ULL; TEST_ULLONG ("65535", -1, -1, -1, 0, _e_, 5, 0, 1, ullmax); TEST_ULLONG ("65536", -1, -1, -1, 0, _ef, 5, 0, 1, ullmax); TEST_ULLONG ("99999", -1, -1, -1, 0, _ef, 5, 0, 1, ullmax); #elif 4 == _RWSTD_ULLONG_SIZE const unsigned long long ullmax = 4294967295ULL; TEST_ULLONG ("4294967295", -1, -1, -1, 0, _e_, 10, 0, -1, ullmax); TEST_ULLONG ("4294967296", -1, -1, -1, 0, _ef, 10, 0, -1, ullmax); TEST_ULLONG ("9999999999", -1, -1, -1, 0, _ef, 10, 0, -1, ullmax); #elif 8 == _RWSTD_ULLONG_SIZE const unsigned long long ullmax = 9223372036854775807ULL; TEST_ULLONG ("9223372036854775807", -1, -1, -1, 0, _e_, 10, 0, -1, ullmax); TEST_ULLONG ("9223372036854775808", -1, -1, -1, 0, _ef, 10, 0, -1, ullmax); TEST_ULLONG ("9999999999999999999", -1, -1, -1, 0, _ef, 10, 0, -1, ullmax); #endif // _RWSTD_ULLONG_SIZE } /***********************************************************************/ template void test_floating (CharT*, Traits*, FloatingType*, const char *cname, const char *tname, const char *fname, const char *fmt) { typedef FloatingType T; test_extractor ((CharT*)0, (Traits*)0, (FloatingType*)0, cname, tname, fname, fmt); #define TEST_FLOATING(ss, fl, is, ex, ee, es, ne, fw, iv, ev) \ TEST (T, fmt, ss, fl, is, ex, ee, es, ne, fw, T (iv), T (ev)) LocaleData locale_data = { 0, -1, -1, 0, 0, 0 }; locale_data.whitespace = ""; TEST_FLOATING ("", -1, -1, -1, 0, _ef, 0, 0, 1.0, 1.0); } /***********************************************************************/ template void test_flt (CharT*, Traits*, const char *cname, const char *tname) { const char fmt[] = "%g"; const char fname[] = "float"; info (cname, tname, fname); test_floating ((CharT*)0, (Traits*)0, (float*)0, cname, tname, fname, fmt); #define TEST_FLT(ss, fl, is, ex, ee, es, ne, fw, iv, ev) \ TEST (float, fmt, ss, fl, is, ex, ee, es, ne, fw, iv, ev) LocaleData locale_data = { 0, -1, -1, 0, 0, 0 }; locale_data.whitespace = ""; TEST_FLT ("", -1, -1, -1, 0, _ef, 0, 0, 1.0f, 1.0f); rw_warn (0, 0, __LINE__, "%{$CLASS}::operator>>(%s&) insufficiently exercised", fname); } /***********************************************************************/ template void test_dbl (CharT*, Traits*, const char *cname, const char *tname) { const char fmt[] = "%g"; const char fname[] = "double"; info (cname, tname, fname); test_floating ((CharT*)0, (Traits*)0, (double*)0, cname, tname, fname, fmt); #define TEST_DBL(ss, fl, is, ex, ee, es, ne, fw, iv, ev) \ TEST (double, fmt, ss, fl, is, ex, ee, es, ne, fw, iv, ev) LocaleData locale_data = { 0, -1, -1, 0, 0, 0 }; locale_data.whitespace = ""; TEST_DBL ("", -1, -1, -1, 0, _ef, 0, 0, 1.0, 1.0); rw_warn (0, 0, __LINE__, "%{$CLASS}::operator>>(%s&) insufficiently exercised", fname); } /***********************************************************************/ template void test_ldbl (CharT*, Traits*, const char *cname, const char *tname) { const char fmt[] = "%Lg"; const char fname[] = "long double"; info (cname, tname, fname); test_floating ((CharT*)0, (Traits*)0, (long double*)0, cname, tname, fname, fmt); #define TEST_LDBL(ss, fl, is, ex, ee, es, ne, fw, iv, ev) \ TEST (long double, fmt, ss, fl, is, ex, ee, es, ne, fw, iv, ev) LocaleData locale_data = { 0, -1, -1, 0, 0, 0 }; locale_data.whitespace = ""; TEST_LDBL ("", -1, -1, -1, 0, _ef, 0, 0, 1.0L, 1.0L); rw_warn (0, 0, __LINE__, "%{$CLASS}::operator>>(%s&) insufficiently exercised", fname); } /***********************************************************************/ int opt_bool; int opt_shrt; int opt_ushrt; int opt_int; int opt_uint; int opt_long; int opt_ulong; int opt_llong; int opt_ullong; int opt_flt; int opt_dbl; int opt_ldbl; template void test_extractor (CharT*, Traits*, const char *cname, const char *tname) { // silence unused variable warnings (void)(___+__f+_e_+_ef+b__+b_f+be_+bef+DEC+OCT+HEX); #undef TEST #define TEST(T) \ if (rw_note (0 == opt_ ## T, 0, __LINE__, "%s tests disabled", #T)) \ test_ ## T ((CharT*)0, (Traits*)0, cname, tname) ////////////////////////////////////////////////////////////////// // basic_istream::operator>>(bool&) TEST (bool); ////////////////////////////////////////////////////////////////// // basic_istream::operator>>(short&) TEST (shrt); ////////////////////////////////////////////////////////////////// // basic_istream::operator>>(unsigned short&) TEST (ushrt); ////////////////////////////////////////////////////////////////// // basic_istream::operator>>(int&) TEST (int); ////////////////////////////////////////////////////////////////// // basic_istream::operator>>(unsigned int&) TEST (uint); ////////////////////////////////////////////////////////////////// // basic_istream::operator>>(long&) TEST (long); ////////////////////////////////////////////////////////////////// // basic_istream::operator>>(unsigned long&) TEST (ulong); ////////////////////////////////////////////////////////////////// // basic_istream::operator>>(long long&) TEST (llong); ////////////////////////////////////////////////////////////////// // basic_istream::operator>>(unsigned long long&) TEST (ullong); ////////////////////////////////////////////////////////////////// // basic_istream::operator>>(float&) TEST (flt); ////////////////////////////////////////////////////////////////// // basic_istream::operator>>(double&) TEST (dbl); ////////////////////////////////////////////////////////////////// // basic_istream::operator>>(long double&) TEST (ldbl); } /***********************************************************************/ static int opt_char; static int opt_wchar; static int opt_char_traits; static int opt_user_traits; static int run_test (int, char**) { #undef TEST #define TEST(CharT, Traits) \ test_extractor ((CharT*)0, (Traits*)0, #CharT, #Traits) if (rw_note (0 <= opt_char && 0 <= opt_char_traits, 0, __LINE__, "basic_istream>::operator>>() " "tests disabled")) TEST (char, std::char_traits); if (rw_note (0 <= opt_char && 0 <= opt_user_traits, 0, __LINE__, "basic_istream>::operator>>() " "tests disabled")) TEST (char, UserTraits); #ifndef _RWSTD_NO_WCHAR_T if (rw_note (0 <= opt_wchar && 0 <= opt_char_traits, 0, __LINE__, "basic_istream>::operator>>() " "tests disabled")) TEST (wchar_t, std::char_traits); if (rw_note (0 <= opt_wchar && 0 <= opt_user_traits, 0, __LINE__, "basic_istream>::operator>>() " "tests disabled")) TEST (wchar_t, UserTraits); #endif // _RWSTD_NO_WCHAR_T return 0; } /***********************************************************************/ int main (int argc, char *argv[]) { return rw_test (argc, argv, __FILE__, "istream.formatted.arithmetic", 0 /* no comment */, run_test, "|-char~ " "|-wchar_t~ " "|-char_traits~ " "|-UserTraits~ " "|-bool~ " "|-short~ " "|-unsigned-short~ " "|-int~ " "|-unsigned-int~ " "|-long~ " "|-unsigned-long~ " "|-long-long~ " "|-unsigned-long-long~ " "|-float~ " "|-double~ " "|-long-double~ " "|-no-gcount# ", &opt_char, &opt_wchar, &opt_char_traits, &opt_user_traits, &opt_bool, &opt_shrt, &opt_ushrt, &opt_int, &opt_uint, &opt_long, &opt_ulong, &opt_llong, &opt_ullong, &opt_flt, &opt_dbl, &opt_ldbl, &opt_no_gcount, (void*)0 /* sentinel */); }