/************************************************************************
 *
 * 27.istream.manip.cpp - test exercising the basic_istream ws manipulator
 *
 * $Id$
 *
 ************************************************************************
 *
 * 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.
 *
 * Copyright 2003-2006 Rogue Wave Software.
 * 
 **************************************************************************/

#include <cstddef>
#include <istream>

#include <driver.h>

/************************************************************************

    namespace std {
        template <class charT, class traits>
        basic_istream<charT,traits>& ws(basic_istream<charT,traits>& is);
    }

    -1- Effects: Extracts characters as long as the next available
        character c is whitespace or until there are no more characters
        in the sequence. Whitespace characters are distinguished with
        the same criterion as used by sentry::sentry (27.6.1.1.2). If
        ws stops extracting characters because there are no more
        available it sets eofbit, but not failbit.
    -2- Returns: is

************************************************************************/

template <class charT>
struct Ctype: std::ctype<charT>
{
    typedef std::ctype<charT> Base;

    const charT ws_;   // whitespace character

    std::ctype_base::mask table_ [256];

    Ctype (std::size_t ref, charT white)
        : Base (ref), ws_ (white) { }

    // used by ctype<wchar_t>
    /* virtual */ bool
    do_is (std::ctype_base::mask m, charT c) const {
        if (m & std::ctype_base::space)
            return ws_ == c;
        return Base::is (m, c);
    }

    // not used by the test, defined only to silence compiler warnings
    // about the overload above hiding the base function overloaded below
    /* virtual */ const charT*
    do_is (const charT *lo, const charT *hi, std::ctype_base::mask *m) const {
        return Base::do_is (lo, hi, m);
    }
};


// specialized for ctype<char>
_RWSTD_SPECIALIZED_CLASS
Ctype<char>::Ctype (std::size_t ref, char white)
    : Base (table_, false, ref), ws_ (white)
{
    for (std::size_t i = 0; i != sizeof table_ / sizeof *table_; ++i)
        table_ [i] = std::ctype_base::mask ();

    typedef unsigned char UChar;

    table_ [UChar (ws_)] = std::ctype_base::space;
}


// user-defined Traits type exercises the ability to instantiate
// std::ws and any supporting templates on types other than the
// default std::char_traits<charT>
template <class charT>
struct UserTraits: std::char_traits<charT> { };


template <class charT, class Traits>
struct Streambuf: std::basic_streambuf<charT, Traits>
{
    typedef std::basic_streambuf<charT, Traits> Base;

    typedef typename Base::traits_type          traits_type;
    typedef typename Base::int_type             int_type;

    int nsyncs_;       // number of calls to sync()

    // overflow() will return eof () after extracting this many chars
    int fail_after_;

    // overflow() will throw am exception after extracting this many chars
    int throw_after_;

    const charT *end_;          // the end of the buffer (future eback())

    Streambuf (const charT *gbeg, const charT *gend)
        : Base (),
          nsyncs_ (0),
          fail_after_ (-1),    // never fail
          throw_after_ (-1),   // never throw
          end_ (gend) {
        this->setg (_RWSTD_CONST_CAST (charT*, gbeg),
                    _RWSTD_CONST_CAST (charT*, gbeg),
                    _RWSTD_CONST_CAST (charT*, gbeg));
    }

    const charT* pubeback () const {
        return this->eback ();
    }

    const charT* pubgptr () const {
        return this->gptr ();
    }

    const charT* pubegptr () const {
        return this->egptr ();
    }

    /* virtual */ int sync () {
        ++nsyncs_;
        return Base::sync ();
    }

    /* virtual */ int_type underflow () {
        if (this->gptr () == end_)
            return traits_type::eof ();

        if (throw_after_ == this->gptr () - this->eback ()) {

#ifndef _RWSTD_NO_EXCEPTIONS

            throw throw_after_;

#else   // if defined (_RWSTD_NO_EXCEPTIONS)

            return traits_type::eof ();

#endif   // _RWSTD_NO_EXCEPTIONS

        }

        if (fail_after_ == this->gptr () - this->eback ())
            return traits_type::eof ();

        this->setg (this->eback (), this->gptr (), this->gptr () + 1);
        return traits_type::to_int_type (*this->gptr ());
    }
};

/***********************************************************************/

template <class charT, class Traits>
void
test_ws (const Traits*           /* dummy */,
         const char             *cname,
         const char             *tname,
         std::size_t             iter,
         const charT            *cbuf,
         std::size_t             cbuf_size,
         std::ios_base::iostate  state,
         std::size_t             j,
         bool                    skipws,
         charT                   white)
{
    typedef std::basic_istream<charT, Traits>   Istream;
    typedef typename Istream::sentry            Sentry;

    // construct a ctype object that treats `wc' as the only
    // whitespace character
    const Ctype<charT> ctp (1, white);

    // construct a stream buffer object and initialize its read sequence
    // with the character buffer
    Streambuf<charT, Traits> sb (cbuf, cbuf + cbuf_size - 1);

    // set err_after to the number of successful extractions from
    // the stream; subsequent extraction will cause an error
    const std::size_t err_after = j % (cbuf_size - 1);
    const char *err_type;

    if (j < cbuf_size - 1) {
        // have the stream buffer object's underflow() fail (by throwing
        // an exception if possible) after j characters have been extracted
        // (this object calls underflow() for every char)
        sb.throw_after_ = err_after;
        err_type        = "threw";
    }
    else {
        // have the stream buffer object's underflow() fail by returning
        // eof after j characters have been extracted (this object calls
        // underflow() for every char)
        sb.fail_after_ = err_after;
        err_type       = "returned EOF";
    }

    // construct an istream object and initialize it with the user
    // defined streambuf object
    Istream is (&sb);

    // set the stream object's initial state
    is.setstate (state);

    // set or clear the skipws bit
    if (skipws)
        is.setf (std::ios_base::skipws);
    else
        is.unsetf (std::ios_base::skipws);

    // construct a locale object containing the user-defined ctype object
    const std::locale loc = is.imbue (std::locale (is.getloc (), &ctp));

    // 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);

    // the number of extracted whitespace characters expected to
    // be reported by gcount() must equal the number of successful
    // extractions computed by the the stream buffer overridden
    // underflow member function
    const int extract = is.good () && white == cbuf [0] ? int (err_after) : 0;

#ifndef _RWSTD_NO_EXCEPTIONS

    bool caught = false;

    // on every other iteration set badbit in exceptions to check
    // that the thrown object is propagated by the function
    if (err_after % 2 && !is.bad ())
        is.exceptions (std::ios_base::badbit);

    try {
        std::ws (is);
    }
    catch (int) {
        caught = true;
    }
    catch (...) {

        caught = true;

        rw_assert (false, 0, __LINE__,
                   "%u. std::ws (basic_istream<%s, %s >&);"
                   " threw exception of unexpected type",
                   iter, cname, tname);
    }

    //////////////////////////////////////////////////////////////////
    // 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 && !(err_after % 2)), 0, __LINE__,
               "%u. std::ws (basic_istream<%s, %s>&);"
               " unexpectedly propagated exception",
               iter, cname, tname);

#else   // if defined (_RWSTD_NO_EXCEPTIONS)

    std::ws (is);

#endif   // _RWSTD_NO_EXCEPTIONS

    //////////////////////////////////////////////////////////////////
    // verify that the expected number of whitespace characters have
    // been extracted from the stream

    rw_assert (cbuf + extract == sb.pubgptr (), 0, __LINE__,
               "%u. std::ws (basic_istream<%s, %s>&);"
               " expected to extract %d "
               "whitespace chars ('%c') from %{*Ac}, "
               "extracted %u; initial rdstate() = %{Is}, "
               "is.flags() & ios::skipws = %d, "
               "underflow %s at extraction %u",
               iter, cname, tname, extract, (char)(white),
               int (sizeof *cbuf), cbuf,
               sb.pubgptr () - sb.pubeback (), state,
               skipws, err_type, err_after);

    //////////////////////////////////////////////////////////////////
    // verify that gcount() value not affected (27.6.1.4 p1)

    rw_assert (0 == is.gcount (), 0, __LINE__,
               "%u. std::ws (basic_istream<%s, %s >&)."
               "gcount() == %d, got %d; whitespace is"
               " '%c', input is %{*Ac}, initial rdstate() = %{Is}, "
               "flags() & ios::skipws = %d,"
               " underflow %s at extraction %u",
               iter, cname, tname, extract, is.gcount (),
               (char)(white), int (sizeof *cbuf), cbuf, state,
               skipws, err_type, err_after);

    //////////////////////////////////////////////////////////////////
    // verify the state of the stream object after the function call

    // expected stream state after the function call is unchanged
    // (i.e., the initial stream state), // except...
    std::ios_base::iostate expect_state = state;

    if (state) {
        // lwg 419
        expect_state |= std::ios_base::failbit;
    }
    else if (white == cbuf [0] || !err_after) {

#ifndef _RWSTD_NO_EXCEPTIONS

        // ...when any whitespace characters are extracted, or the
        // first character on the stream is peeked at, even if it's
        // not a space, and an exception is thrown during input,
        // badbit should be set, otherwise eofbit (bot not failbit)
        // should be set
        if (j < cbuf_size - 1)
            expect_state = std::ios_base::badbit;
        else
            expect_state = std::ios_base::eofbit;

#else   // if defined (_RWSTD_NO_EXCEPTIONS)

        expect_state = std::ios_base::eofbit;

#endif   // _RWSTD_NO_EXCEPTIONS
    }

    rw_assert (is.rdstate () == expect_state, 0, __LINE__,
               "%u. std::ws (basic_istream<%s, %s >&)."
               "rdstate() == %{Is}, got %{Is}; "
               "extracting whitespace ('%c') from %{*Ac}, "
               "extracted %u; initial is.rdstate() = %{Is}, "
               "is.flags() & ios::skipws = %d, underflow %s "
               "at extraction %u",
               iter, cname, tname,
               expect_state, is.rdstate(),
               (char)(white), int (sizeof *cbuf), cbuf,
               sb.pubgptr () - sb.pubeback (), state,
               skipws, err_type, err_after);
}

/***********************************************************************/


template <class charT, class Traits>
void test_ws (charT*, Traits*, const char *cname, const char *tname)
{
    rw_info (0, 0, __LINE__, "std::basic_istream<%s, %s>& "
             "std::ws (std::basic_istream<%1$s, %2$s>&)",
             cname, tname);

    const charT cbuf[] = { 'a', 'a', 'a', '\0' };
    const std::size_t cbuf_size = sizeof cbuf / sizeof *cbuf;

    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
    };

    const std::size_t nstates = sizeof states / sizeof *states;

    {   //////////////////////////////////////////////////////////////
        // exercise 27.6.1.4, p1

        std::size_t iter = 0;     // iteration counter

        // iterate over all possible settings of the stream state
        for (std::size_t i = 0; i != nstates; ++i) {

            // iterate twice over all characters in the character buffer,
            // once to trigger an exception at each iteration (except
            // the last one), and then again to have underflow() fail
            // by returning EOF at each iteration (except the last one)
            for (std::size_t j = 0; j != 2 * cbuf_size - 1; ++j) {

                // iterate over the ios_base::skipws setting
                for (std::size_t k = 0; k != 2; ++k /* skipws */) {

                    // iterate over two whitespace characters
                    for (charT wc = charT ('a'); wc != charT ('c'); ++wc) {

                        test_ws ((Traits*)0, cname, tname, iter,
                                 cbuf, cbuf_size, states [i], j, !!k, wc);

                        ++iter;
                    }
                }
            }
        }
    }
}

/***********************************************************************/

static int opt_char;
static int opt_wchar;
static int opt_char_traits;
static int opt_user_traits;


static int
run_test (int, char**)
{
#define TEST(charT, Traits) \
    test_ws ((charT*)0, (Traits*)0, #charT, #Traits)

    if (rw_note (0 <= opt_char && 0 <= opt_char_traits, 0, __LINE__,
                 "ws (basic_istream<char, char_traits<char>>) disabled"))
        TEST (char, std::char_traits<char>);

    if (rw_note (0 <= opt_char && 0 <= opt_user_traits, 0, __LINE__,
                 "ws (basic_istream<char, UserTraits<char>>) disabled"))
        TEST (char, UserTraits<char>);

#ifndef _RWSTD_NO_WCHAR_T

    if (rw_note (0 <= opt_wchar && 0 <= opt_char_traits, 0, __LINE__,
                 "ws (basic_istream<wchar_t, char_traits<wchar_t>>) disabled"))
        TEST (wchar_t, std::char_traits<wchar_t>);

    if (rw_note (0 <= opt_wchar && 0 <= opt_user_traits, 0, __LINE__,
                 "ws (basic_istream<wchar_t, UserTraits<wchar_t>>) disabled"))
        TEST (wchar_t, UserTraits<wchar_t>);

#endif   // _RWSTD_NO_WCHAR_T

    return 0;
}

/***********************************************************************/

int main (int argc, char *argv[])
{
    return rw_test (argc, argv, __FILE__,
                    "istream.manip",
                    0 /* no comment */,
                    run_test,
                    "|-char~ "
                    "|-wchar_t~ "
                    "|-char_traits~ "
                    "|-UserTraits~ ",
                    &opt_char,
                    &opt_wchar,
                    &opt_char_traits,
                    &opt_user_traits,
                    (void*)0   /* sentinel */);
}
