Author: sebor
Date: Thu Jan 25 12:32:21 2007
New Revision: 499952
URL: http://svn.apache.org/viewvc?view=rev&rev=499952
Log:
2007-01-25 Martin Sebor <[EMAIL PROTECTED]>
STDCXX-4
* 27.istream.manip.cpp: New test exercising istream.manip.
Added:
incubator/stdcxx/trunk/tests/iostream/27.istream.manip.cpp (with props)
Added: incubator/stdcxx/trunk/tests/iostream/27.istream.manip.cpp
URL:
http://svn.apache.org/viewvc/incubator/stdcxx/trunk/tests/iostream/27.istream.manip.cpp?view=auto&rev=499952
==============================================================================
--- incubator/stdcxx/trunk/tests/iostream/27.istream.manip.cpp (added)
+++ incubator/stdcxx/trunk/tests/iostream/27.istream.manip.cpp Thu Jan 25
12:32:21 2007
@@ -0,0 +1,470 @@
+/************************************************************************
+ *
+ * 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() correctly reflects the number of whitespace
+ // characters extracted from the stream
+
+ rw_assert (extract == 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 && (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 */);
+}
Propchange: incubator/stdcxx/trunk/tests/iostream/27.istream.manip.cpp
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/stdcxx/trunk/tests/iostream/27.istream.manip.cpp
------------------------------------------------------------------------------
svn:keywords = Id