first commit
This commit is contained in:
473
extern/stdcxx/4.2.1/tests/iostream/27.istream.manip.cpp
vendored
Normal file
473
extern/stdcxx/4.2.1/tests/iostream/27.istream.manip.cpp
vendored
Normal file
@@ -0,0 +1,473 @@
|
||||
/************************************************************************
|
||||
*
|
||||
* 27.istream.manip.cpp - test exercising the basic_istream ws manipulator
|
||||
*
|
||||
* $Id: 27.istream.manip.cpp 580483 2007-09-28 20:55:52Z sebor $
|
||||
*
|
||||
************************************************************************
|
||||
*
|
||||
* 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 */);
|
||||
}
|
||||
Reference in New Issue
Block a user