Author: sebor Date: Wed Feb 6 16:16:21 2008 New Revision: 619228 URL: http://svn.apache.org/viewvc?rev=619228&view=rev Log: 2008-02-06 Martin Sebor <[EMAIL PROTECTED]>
STDCXX-645 * include/rw/_streamiter.h (operator*): Checked fail() instead of eof() on the associated stream before turning the object into the end-of-stream iterator, as per LWG issue 788. * tests/iterators/24.istream.iterator.cpp (test_ctors): Inserted a valid number instead of NUL into test stream. (test_ops): Changed the expected result of equality comparison with the end-of-stream iterator according to LWG issue 788. (opt_char, opt_wchar_t, opt_UserTraits, opt_short, opt_int, opt_long, opt_double): Added "tri-state" options. (do_test, run_test, main): Handled said options. Modified: stdcxx/trunk/include/rw/_streamiter.h stdcxx/trunk/tests/iterators/24.istream.iterator.cpp Modified: stdcxx/trunk/include/rw/_streamiter.h URL: http://svn.apache.org/viewvc/stdcxx/trunk/include/rw/_streamiter.h?rev=619228&r1=619227&r2=619228&view=diff ============================================================================== --- stdcxx/trunk/include/rw/_streamiter.h (original) +++ stdcxx/trunk/include/rw/_streamiter.h Wed Feb 6 16:16:21 2008 @@ -120,7 +120,9 @@ operator++ () { // incrementing an end-of-stream iterator has undefined behavior - if (_C_strm && (*_C_strm >> _C_val).eof ()) + + // see also LWG issue 788 + if (_C_strm && (*_C_strm >> _C_val).fail ()) _C_strm = 0; return *this; Modified: stdcxx/trunk/tests/iterators/24.istream.iterator.cpp URL: http://svn.apache.org/viewvc/stdcxx/trunk/tests/iterators/24.istream.iterator.cpp?rev=619228&r1=619227&r2=619228&view=diff ============================================================================== --- stdcxx/trunk/tests/iterators/24.istream.iterator.cpp (original) +++ stdcxx/trunk/tests/iterators/24.istream.iterator.cpp Wed Feb 6 16:16:21 2008 @@ -100,8 +100,7 @@ // below, to prevent the iterator ctor from creating an end-of-stream // iterator (in case it doesn't delay extracting a value until it's // needed) - strm1.rdbuf ()->sputc (CharT ()); - strm1.rdbuf ()->sputc (CharT ()); + strm1 << "1 2 "; // verify [reverse.iter], p3, i.e., that two istream_iterators // constructed from the same stream always compare equal @@ -119,7 +118,7 @@ StringStream strm2; strm2.imbue (strm1.getloc ()); - strm2.rdbuf ()->sputc (CharT ()); + strm2 << "2 "; const Iterator iter3 (strm2); @@ -209,46 +208,58 @@ const bool is_signed = zero - one < zero; const bool is_exact = one / two == zero; + // see LWG issue 788 + // an istream_iterator object becomes an end-of-stream iterator + // after a failed extraction (i.e., when the call to fail() on + // the associated stream returns true) + if (is_char) { + + // +-- controlled sequence + // | +-- extracted value + // | | +-- iterator equal to EOS after extraction + // | | | +-- stream state after extraction + // | | | | + // V V V V TEST ("", '\0', true, Eof | Fail); TEST ("1", '1', false, Good); TEST ("2", '2', false, Good); } else { TEST ("", 0, true, Eof | Fail); - TEST ("1", 1, true, Eof); + TEST ("1", 1, false, Eof); TEST ("1 ", 1, false, Good); - TEST ("+1", 1, true, Eof); - TEST (" 1", 1, true, Eof); + TEST ("+1", 1, false, Eof); + TEST (" 1", 1, false, Eof); TEST (" 1 ", 1, false, Good); - TEST (" +1", 1, true, Eof); - TEST ("2", 2, true, Eof); - TEST ("+2", 2, true, Eof); - TEST (" 2", 2, true, Eof); - TEST (" +2", 2, true, Eof); - TEST ("99", 99, true, Eof); - TEST ("+99", 99, true, Eof); - TEST (" 99", 99, true, Eof); - TEST (" +99", 99, true, Eof); + TEST (" +1", 1, false, Eof); + TEST ("2", 2, false, Eof); + TEST ("+2", 2, false, Eof); + TEST (" 2", 2, false, Eof); + TEST (" +2", 2, false, Eof); + TEST ("99", 99, false, Eof); + TEST ("+99", 99, false, Eof); + TEST (" 99", 99, false, Eof); + TEST (" +99", 99, false, Eof); TEST ("+", 0, true, Eof | Fail); TEST ("-", 0, true, Eof | Fail); TEST (" +", 0, true, Eof | Fail); TEST (" -", 0, true, Eof | Fail); - TEST ("++", 0, false, Fail); - TEST ("--", 0, false, Fail); - TEST (" ++", 0, false, Fail); - TEST (" --", 0, false, Fail); - TEST ("*", 0, false, Fail); - TEST (" *", 0, false, Fail); + TEST ("++", 0, true, Fail); + TEST ("--", 0, true, Fail); + TEST (" ++", 0, true, Fail); + TEST (" --", 0, true, Fail); + TEST ("*", 0, true, Fail); + TEST (" *", 0, true, Fail); if (is_signed) { - TEST ("-1", -1, true, Eof); - TEST (" -1", -1, true, Eof); - TEST ("-2", -2, true, Eof); - TEST (" -2", -2, true, Eof); - TEST ("-99", -99, true, Eof); - TEST (" -99", -99, true, Eof); + TEST ("-1", -1, false, Eof); + TEST (" -1", -1, false, Eof); + TEST ("-2", -2, false, Eof); + TEST (" -2", -2, false, Eof); + TEST ("-99", -99, false, Eof); + TEST (" -99", -99, false, Eof); } if (is_exact) { @@ -258,27 +269,27 @@ TEST (" +4.", 4, false, Good); } else { - TEST (".1", 0.1, true, Eof); - TEST ("+.2", 0.2, true, Eof); - TEST ("-.3", -0.3, true, Eof); - TEST (" +.4", 0.4, true, Eof); - TEST (" -.5", -0.5, true, Eof); + TEST (".1", 0.1, false, Eof); + TEST ("+.2", 0.2, false, Eof); + TEST ("-.3", -0.3, false, Eof); + TEST (" +.4", 0.4, false, Eof); + TEST (" -.5", -0.5, false, Eof); TEST ("1..", 1.0, false, Good); - TEST ("1.234", 1.234, true, Eof); - TEST ("+1.235", +1.235, true, Eof); - TEST ("-1.236", -1.236, true, Eof); - TEST (" +1.237", +1.237, true, Eof); - TEST (" -1.238", -1.238, true, Eof); - TEST ("1.239e1", 1.239e1, true, Eof); - TEST ("1.240e+1", 1.240e+1, true, Eof); - TEST ("-1.241e+2", -1.241e+2, true, Eof); + TEST ("1.234", 1.234, false, Eof); + TEST ("+1.235", +1.235, false, Eof); + TEST ("-1.236", -1.236, false, Eof); + TEST (" +1.237", +1.237, false, Eof); + TEST (" -1.238", -1.238, false, Eof); + TEST ("1.239e1", 1.239e1, false, Eof); + TEST ("1.240e+1", 1.240e+1, false, Eof); + TEST ("-1.241e+2", -1.241e+2, false, Eof); TEST ("-1.242e-3 ", -1.242e-3, false, Good); TEST ("1.3e", 0, true, Eof | Fail); TEST ("1.4e+", 0, true, Eof | Fail); TEST ("1.5e-", 0, true, Eof | Fail); - TEST ("1.6e+ ", 0, false, Fail); + TEST ("1.6e+ ", 0, true, Fail); } } } @@ -309,6 +320,15 @@ /***********************************************************************/ +int opt_char; +int opt_wchar_t; +int opt_UserTraits; +int opt_short; +int opt_int; +int opt_long; +int opt_double; + + // exercise different specializations of T template <class CharT, class Traits, class Dist> void do_test (TestId id, @@ -318,7 +338,8 @@ { #undef TEST #define TEST(T, fmt) \ - do_test<T, CharT, Traits, Dist>(id, #T, fmt, cname, trname, dname) + if (opt_ ## T) \ + do_test<T, CharT, Traits, Dist>(id, #T, fmt, cname, trname, dname) // cannot instantiate basic_istream<CharT>::operator>>(char&) // for any CharT other than char @@ -348,6 +369,15 @@ { static const TestId test_ids [] = { TestCtors, TestOps }; + if (opt_char < 0) + rw_note (0, 0, __LINE__, "tests of char specialization disabled"); + + if (opt_wchar_t < 0) + rw_note (0, 0, __LINE__, "tests of wchar_t specialization disabled"); + + if (opt_UserTraits < 0) + rw_note (0, 0, __LINE__, "tests of UserTraits specialization disabled"); + typedef std::char_traits<char> Traits; typedef UserTraits<char> UsrTraits; @@ -355,25 +385,38 @@ const TestId id = test_ids [i]; - // call these helper functions directly to avoid instantiating - // basic_istream<CharT>::operator>>(char&) on any CharT other - // than char - do_test<char, char, Traits, std::ptrdiff_t>(id, "char", "%{hhi}", - 0, 0, 0); - do_test<char, char, UsrTraits, std::ptrdiff_t>(id, "char", "%{hhi}", - 0, "UserTraits<char>", - "std::ptrdiff_t"); + if (0 <= opt_char) { - do_test<char, Traits>(id, 0, 0); - do_test<char, UsrTraits>(id, "char", "UserTraits<char>"); + // call these helper functions directly to avoid instantiating + // basic_istream<CharT>::operator>>(char&) on any CharT other + // than char + do_test<char, char, Traits, std::ptrdiff_t>(id, "char", "%{hhi}", + 0, 0, 0); + + if (0 <= opt_UserTraits) + do_test<char, char, UsrTraits, std::ptrdiff_t>(id, "char", + "%{hhi}", 0, "UserTraits<char>", "std::ptrdiff_t"); + + do_test<char, Traits>(id, 0, 0); + + if (0 <= opt_UserTraits) + do_test<char, UsrTraits>(id, "char", "UserTraits<char>"); + } #ifndef _RWSTD_NO_WCHAR_T - typedef std::char_traits<wchar_t> WTraits; - typedef UserTraits<wchar_t> WUsrTraits; + if (0 <= opt_wchar_t) { + + typedef std::char_traits<wchar_t> WTraits; + typedef UserTraits<wchar_t> WUsrTraits; - do_test<wchar_t, WTraits>(id, 0, 0); - do_test<wchar_t, WUsrTraits>(id, "wchar_t", "UserTraits<wchar_t>"); + do_test<wchar_t, WTraits>(id, 0, 0); + + if (0 <= opt_UserTraits) + do_test<wchar_t, WUsrTraits>(id, "wchar_t", + "UserTraits<wchar_t>"); + + } #endif // _RWSTD_NO_WCHAR_T @@ -391,5 +434,19 @@ "lib.istream.iterator", 0 /* no comment */, run_test, - "", 0); + "|-char~ " + "|-wchar_t~ " + "|-UserTraits~ " + "|-short~ " + "|-int~ " + "|-long~ " + "|-double~ ", + &opt_char, + &opt_wchar_t, + &opt_UserTraits, + &opt_short, + &opt_int, + &opt_long, + &opt_double, + (void*)0 /* sentinel */); }