void test_ctor (const charT*, const Traits*, const char *cname, const char *tname) { typedef std::basic_istream<charT, Traits> Istream; typedef typename Istream::sentry Sentry; memfun_info (__LINE__, cname, tname, "sentry (%{$ISTREAM}&, bool)"); const charT cbuf[] = { 'a', 'b', 'c', 'd', 'e', ' ', 'f', '\0' }; const std::ios_base::iostate states[] = { std::ios_base::badbit, std::ios_base::eofbit, std::ios_base::failbit, std::ios_base::goodbit, std::ios_base::badbit | std::ios_base::eofbit, std::ios_base::badbit | std::ios_base::failbit, std::ios_base::eofbit | std::ios_base::failbit, std::ios_base::badbit | std::ios_base::eofbit | std::ios_base::failbit }; ////////////////////////////////////////////////////////////// // exercise 27.6.1.1.2, p1: // - is.good() is true // - is.tie() is not null // = the function calls is.tie().flush() unsigned iter = 0; // iteration counter for (unsigned i = 0; i != sizeof states / sizeof *states; ++i) { for (unsigned j = 0; j != 2; ++j /* noskipws */) { Streambuf<charT, Traits> sb (cbuf, cbuf + sizeof cbuf / sizeof *cbuf); Istream is (&sb); // flush() is called iff // all of the following conditions hold const bool flush_called = is.good () && 0 != is.tie (); const Sentry guard (is, 0 != j); _RWSTD_UNUSED (guard); rw_assert (flush_called == sb.nsyncs_, 0, __LINE__, "%u. basic_istream<%s, %s>::sentry::sentry" "(basic_istream &is, bool noskipws = %d); " "expected to call is.flush () %d times, got %d" "initial is.state () = %{Is}, is.flags() & " "ios::skipws = %d", iter, cname, tname, 0 != j, flush_called, sb.nsyncs_, states [i], is.flags () & std::ios_base::skipws); ++iter; } } ////////////////////////////////////////////////////////////// // exercise 27.6.1.1.2, p1: // - is.good() is true // - noskipws is zero // - is.flags() & ios_base::skipws // = the function extracts and discards each character as long // as the next available input character c is a whitespace // character. for (unsigned i = 0; i != sizeof states / sizeof *states; ++i) { for (unsigned j = 0; j != 2; ++j /* noskipws */) { for (unsigned k = 0; k != 2; ++k /* ios_base::skipws */) { for (charT wc = charT ('a'); wc != charT ('c'); ++wc) { const Ctype<charT> ctp (1, wc); Streambuf<charT, Traits> sb (cbuf, cbuf + sizeof cbuf / sizeof *cbuf); Istream is (&sb); is.setstate (states [i]); if (k) is.setf (std::ios_base::skipws); else is.unsetf (std::ios_base::skipws); const std::locale loc = is.imbue (std::locale (is.getloc (), &ctp)); // imbue the previous locale into the stream // buffer to verify that the sentry ctor uses // the locale imbued in the stream object and // not the one in the stream buffer sb.pubimbue (loc); // a whitespace character is extracted iff // all of the following conditions hold const bool extract = is.good () && 0 == j && is.flags () & std::ios_base::skipws && cbuf [0] == wc; const Sentry guard (is, 0 != j); _RWSTD_UNUSED (guard); rw_assert (cbuf + extract == sb.pubgptr (), 0, __LINE__, "%u. %{$SENTRY}::sentry" "(%{$ISTREAM} &is, bool noskipws " "= %b); expected to extract %d " "whitespace chars ('%c') from %{*Ac}, " "extracted %u; initial is.state () = " "%{Is}, is.flags() & ios::skipws = %d", iter, j, extract + 0, char (wc), int (sizeof (*cbuf)), cbuf, sb.pubgptr () - sb.pubeback (), states [i], k); // verify that the ctor doesn't affect gcount() rw_assert (0 == is.gcount (), 0, __LINE__, "%u. %{$SENTRY}::sentry" "(%{$ISTREAM} &is = %{*Ac}, bool noskipws " "= %b); changed is.gcount() from 0 to %i", iter, int (sizeof (*cbuf)), cbuf, j, is.gcount ()); ++iter; } } } } }