Example #1
0
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;
                }
            }
        }
    }
}