first commit

This commit is contained in:
Jose Caban
2025-06-07 11:34:38 -04:00
commit 0eb2d7c07d
4708 changed files with 1500614 additions and 0 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,243 @@
/***************************************************************************
*
* 27.forward.cpp - exercises lib.iostream.forward
*
* $Id: 27.forward.cpp 451936 2006-10-02 09:51:24Z faridz $
*
***************************************************************************
*
* 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 1994-2005 Rogue Wave Software.
*
**************************************************************************/
#include <iosfwd>
// IMPORTANT: do not #include any other header before the declarations
// below in order not to accidentally bring in any missing
// definitions from the #included header
#ifndef _RWSTD_NO_NAMESPACE
# define std std
#else
# define std
#endif // _RWSTD_NO_NAMESPACE
typedef char C;
typedef std::char_traits<C> ctraits;
typedef std::allocator<C> calloc;
typedef std::basic_ios<C, ctraits> C_basic_ios;
typedef std::basic_streambuf<C, ctraits> C_basic_streambuf;
typedef std::basic_istream<C, ctraits> C_basic_istream;
typedef std::basic_ostream<C, ctraits> C_basic_ostream;
typedef std::basic_iostream<C, ctraits> C_basic_iostream;
typedef std::basic_stringbuf<C, ctraits, calloc> C_basic_stringbuf;
typedef std::basic_istringstream<C, ctraits, calloc> C_basic_istringstream;
typedef std::basic_ostringstream<C, ctraits, calloc> C_basic_ostringstream;
typedef std::basic_stringstream<C, ctraits, calloc> C_basic_stringstream;
typedef std::basic_filebuf<C, ctraits> C_basic_filebuf;
typedef std::basic_ifstream<C, ctraits> C_basic_ifstream;
typedef std::basic_ofstream<C, ctraits> C_basic_ofstream;
typedef std::basic_fstream<C, ctraits> C_basic_fstream;
typedef std::istreambuf_iterator<C, ctraits> C_istreambuf_iterator;
typedef std::ostreambuf_iterator<C, ctraits> C_ostreambuf_iterator;
#ifndef _RWSTD_NO_COMPLEX_DEFAULT_TEMPLATES
// make sure that default template arguments are specified
typedef std::basic_ios<C> C_X_basic_ios;
typedef std::basic_streambuf<C> C_X_basic_streambuf;
typedef std::basic_istream<C> C_X_basic_istream;
typedef std::basic_ostream<C> C_X_basic_ostream;
typedef std::basic_iostream<C> C_X_basic_iostream;
typedef std::basic_stringbuf<C> C_X_basic_stringbuf;
typedef std::basic_istringstream<C> C_X_basic_istringstream;
typedef std::basic_ostringstream<C> C_X_basic_ostringstream;
typedef std::basic_stringstream<C> C_X_basic_stringstream;
typedef std::basic_filebuf<C> C_X_basic_filebuf;
typedef std::basic_ifstream<C> C_X_basic_ifstream;
typedef std::basic_ofstream<C> C_X_basic_ofstream;
typedef std::basic_fstream<C> C_X_basic_fstream;
typedef std::istreambuf_iterator<C> C_X_istreambuf_iterator;
typedef std::ostreambuf_iterator<C> C_X_ostreambuf_iterator;
#endif // _RWSTD_NO_COMPLEX_DEFAULT_TEMPLATES
typedef std::fpos<C> C_fpos;
// test whether all required typedefs are defined
typedef std::ios C_ios;
typedef std::streambuf C_streambuf;
typedef std::istream C_istream;
typedef std::ostream C_ostream;
typedef std::iostream C_iostream;
typedef std::stringbuf C_stringbuf;
typedef std::istringstream C_istringstream;
typedef std::ostringstream C_ostringstream;
typedef std::stringstream C_stringstream;
typedef std::filebuf C_filebuf;
typedef std::ifstream C_ifstream;
typedef std::ofstream C_ofstream;
typedef std::fstream C_fstream;
typedef std::streampos C_streampos;
#ifndef _RWSTD_NO_WCHAR_T
typedef std::wios W_wios;
typedef std::wstreambuf W_wstreambuf;
typedef std::wistream W_wistream;
typedef std::wostream W_wostream;
typedef std::wiostream W_wiostream;
typedef std::wstringbuf W_wstringbuf;
typedef std::wistringstream W_wistringstream;
typedef std::wostringstream W_wostringstream;
typedef std::wstringstream W_wstringstream;
typedef std::wfilebuf W_wfilebuf;
typedef std::wifstream W_wifstream;
typedef std::wofstream W_wofstream;
typedef std::wfstream W_wfstream;
typedef std::wstreampos W_wstreampos;
#endif // _RWSTD_NO_WCHAR_T
/**************************************************************************/
#include <driver.h>
/**************************************************************************/
#ifndef _RWSTD_NO_PART_SPEC_OVERLOAD
template <class T, class U>
bool is_same_type (const T*, const U*) { return false; }
template <class T>
bool is_same_type (const T*, const T*) { return true; }
#else // ifdef _RWSTD_NO_PART_SPEC_OVERLOAD
template <class T, class U>
struct is_same
{
struct yes {};
struct no { yes no_ [2]; };
template <class T>
struct Type {};
static yes test (Type<T>, Type<T>);
static no test (...);
enum { value = sizeof (test (Type<T> (), Type<U> ())) == sizeof (yes) };
};
template <class T, class U>
bool is_same_type (const T*, const U*) { return is_same<T, U>::value; }
#endif // _RWSTD_NO_PART_SPEC_OVERLOAD
/**************************************************************************/
static int
run_test (int, char*[])
{
#define TEST_TYPE(T) \
rw_assert (is_same_type ((C_X_ ## T*)0, (C_ ## T*)0), 0, __LINE__, \
"%s", #T);
// check that default arguments are correct
TEST_TYPE (basic_ios);
TEST_TYPE (basic_streambuf);
TEST_TYPE (basic_istream);
TEST_TYPE (basic_ostream);
TEST_TYPE (basic_iostream);
TEST_TYPE (basic_stringbuf);
TEST_TYPE (basic_istringstream);
TEST_TYPE (basic_ostringstream);
TEST_TYPE (basic_stringstream);
TEST_TYPE (basic_filebuf);
TEST_TYPE (basic_ifstream);
TEST_TYPE (basic_ofstream);
TEST_TYPE (basic_fstream);
TEST_TYPE (istreambuf_iterator);
TEST_TYPE (ostreambuf_iterator);
#define TEST_TYPEDEF(T, U) \
rw_assert (is_same_type ((T*)0, (U*)0), 0, __LINE__, \
"%s == %s", #T, #U);
// check that typedefs are correctly defined
TEST_TYPEDEF (std::ios, C_ios);
TEST_TYPEDEF (std::streambuf, C_streambuf);
TEST_TYPEDEF (std::istream, C_istream);
TEST_TYPEDEF (std::ostream, C_ostream);
TEST_TYPEDEF (std::iostream, C_iostream);
TEST_TYPEDEF (std::stringbuf, C_stringbuf);
TEST_TYPEDEF (std::istringstream, C_istringstream);
TEST_TYPEDEF (std::ostringstream, C_ostringstream);
TEST_TYPEDEF (std::stringstream, C_stringstream);
TEST_TYPEDEF (std::filebuf, C_filebuf);
TEST_TYPEDEF (std::ifstream, C_ifstream);
TEST_TYPEDEF (std::ofstream, C_ofstream);
TEST_TYPEDEF (std::fstream, C_fstream);
#ifndef _RWSTD_NO_WCHAR_T
TEST_TYPEDEF (std::wios, W_wios);
TEST_TYPEDEF (std::wstreambuf, W_wstreambuf);
TEST_TYPEDEF (std::wistream, W_wistream);
TEST_TYPEDEF (std::wostream, W_wostream);
TEST_TYPEDEF (std::wiostream, W_wiostream);
TEST_TYPEDEF (std::wstringbuf, W_wstringbuf);
TEST_TYPEDEF (std::wistringstream, W_wistringstream);
TEST_TYPEDEF (std::wostringstream, W_wostringstream);
TEST_TYPEDEF (std::wstringstream, W_wstringstream);
TEST_TYPEDEF (std::wfilebuf, W_wfilebuf);
TEST_TYPEDEF (std::wifstream, W_wifstream);
TEST_TYPEDEF (std::wofstream, W_wofstream);
TEST_TYPEDEF (std::wfstream, W_wfstream);
TEST_TYPEDEF (std::wstreampos, std::streampos);
#endif // _RWSTD_NO_WCHAR_T
return 0;
}
/**************************************************************************/
int main (int argc, char *argv[])
{
return rw_test (argc, argv, __FILE__,
"lib.iostream.forward",
0, // no comment
run_test,
"",
0);
}

File diff suppressed because it is too large Load Diff

View 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 */);
}

View File

@@ -0,0 +1,476 @@
/************************************************************************
*
* 27.readsome.cpp - test exercising istream::readsome()
*
* $Id: 27.istream.readsome.cpp 503954 2007-02-06 01:59:05Z 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-2007 Rogue Wave Software.
*
**************************************************************************/
#include <istream>
#include <sstream>
#include <driver.h>
#include <rw_char.h> // for UserChar, UserTraits
#include <rw_printf.h> // for rw_printf()
/***********************************************************************/
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;
// value returned from showmanyc()
int showmanyc_;
// underflow() will return eof () after extracting this many chars
int fail_after_;
// underflow() 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 (),
showmanyc_ (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 */ std::streamsize showmanyc () {
#ifndef _RWSTD_NO_EXCEPTIONS
if (-2 == showmanyc_)
throw (const char*)"showmanyc";
#endif // _RWSTD_NO_EXCEPTIONS
return showmanyc_;
}
/* virtual */ int_type underflow () {
if (this->gptr () == end_)
return traits_type::eof ();
if (throw_after_ == this->gptr () - this->eback ()) {
#ifndef _RWSTD_NO_EXCEPTIONS
throw (const char*)"underflow";
#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 ());
}
};
/***********************************************************************
27.6.1.3, p30 and 31
streamsize readsome (char_type* s, streamsize n);
-30- Effects: If !good() calls setstate(failbit) which may throw an
exception, and return. Otherwise extracts characters and stores
them into successive locations of an array whose first element
is designated by s.
-- If rdbuf()<29>>in_avail() == <20>1, calls setstate(eofbit) (which
may throw ios_base::failure (27.4.4.3)), and extracts no
characters;
-- If rdbuf()<29>>in_avail() == 0, extracts no characters
-- If rdbuf()<29>>in_avail() > 0, extracts min(rdbuf()<29>>in_avail(),
n)).
-31- Returns: The number of characters extracted.
************************************************************************/
void
memfun_info (int line, const char *cname, const char *tname)
{
// format the ISTREAM environment variable w/o writing
// out any output
rw_fprintf (0,
"%{$ISTREAM!:@}",
"%{?}istream%{:}%{?}wistream"
"%{:}basic_istream<%s, %s>%{;}%{;}",
'c' == *cname && 'c' == *tname,
'w' == *cname && 'c' == *tname,
cname, tname);
rw_info (0, 0, line,
"std::%{$ISTREAM}::readsome (char_type*, streamsize)");
}
/************************************************************************/
extern 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
};
extern const unsigned nstates = sizeof states / sizeof *states;
template <class charT, class Traits>
void test_readsome (const charT *cbuf, const Traits*,
unsigned cbuf_size,
unsigned i, // index into states
unsigned j, // number of chars to read
unsigned k, // when underflow() will fail
int l, // value returned from showmanyc()
unsigned m) // how underflow should fail()
{
typedef std::basic_istream<charT, Traits> Istream;
static unsigned iter = 0; // iteration counter
// construct a stream buffer object and initialize its read
// sequence with the character buffer
Streambuf<charT, Traits> sb (cbuf, cbuf + cbuf_size - 1);
sb.showmanyc_ = l;
const char* err_type = 0;
if (m < 1) {
// have the stream buffer object's underflow() fail (by
// throwing an exception if possible) after k characters
// have been extracted (this object calls underflow() for
// every char)
sb.throw_after_ = k;
err_type = "threw";
}
else {
// have the stream buffer object's underflow() fail by
// returning eof after k characters have been extracted
// (this object calls underflow() for every char)
sb.fail_after_ = k;
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 (states [i]);
// 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 () ? j < k ? int (j) < l ? j
: l < 0 ? 0 : l
: int (k) < l ? k
: l < 0 ? 0 : l
: 0;
charT buf [256] = { 0 };
std::streamsize nread = -1;
// format the FCALL environment variable so that it can be
// conveniently used in diagnostics below
rw_fprintf (0, "%u. %{$FCALL!:@}",
iter,
"%{$ISTREAM}(%{*Ac}).readsome(%p, %d)",
int (sizeof *cbuf), cbuf, buf, j);
#ifndef _RWSTD_NO_EXCEPTIONS
const char *caught = 0;
// on every other iteration set badbit in exceptions to check
// that the thrown object is propagated by the function
if (k % 2 && !is.bad ())
is.exceptions (std::ios_base::badbit);
try {
nread = is.readsome (buf, j);
}
catch (const char *s) {
caught = s;
}
catch (...) {
caught = "...";
rw_assert (0, 0, __LINE__,
"%{$FCALL} threw an exception of unexpected type");
}
//////////////////////////////////////////////////////////////////
// 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 || (k % 2), 0, __LINE__,
"%{$FCALL} unexpectedly propagated an exception");
#else // if defined (_RWSTD_NO_EXCEPTIONS)
nread = is.readsome (buf, j);
#endif // _RWSTD_NO_EXCEPTIONS
//////////////////////////////////////////////////////////////////
// verify that the function returned the expected number of
// extracted characters
const std::streamsize extracted = sb.pubgptr () - sb.pubeback ();
rw_assert (extract == extracted, 0, __LINE__,
"%{$FCALL} expected to extract %d chars, got %u; "
"initial state = %{Is}, underflow %s at extraction %u",
extract, extracted, states [i],
err_type, k);
//////////////////////////////////////////////////////////////////
// verify that the expected number of characters have been
// extracted from the stream
rw_assert (cbuf + extract == sb.pubgptr (), 0, __LINE__,
"%{$FCALL} expected to extract %d chars, got %u; "
"initial state = %{Is}, underflow %s at extraction %u",
extract, extracted, states [i],
err_type, k);
//////////////////////////////////////////////////////////////////
// verify that the extracted characters match those in the buffer
rw_assert (0 == std::char_traits<charT>::compare (buf, cbuf, extract),
0, __LINE__,
"%{$FCALL} expected to extract the first %d chars, got %{*Ac}",
extract, int (sizeof *buf), buf);
//////////////////////////////////////////////////////////////////
// verify that gcount() correctly reflects the number of
// characters successfully extracted from the stream
rw_assert (extract == is.gcount (), 0, __LINE__,
"%{$FCALL}: gcount() == %d, got %d; initial state = %{Is}, "
"underflow %s at extraction %u",
extract, is.gcount (), states [i],
err_type, k);
//////////////////////////////////////////////////////////////////
// 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 = states [i];
if (!states [i]) {
#ifndef _RWSTD_NO_EXCEPTIONS
// ...if an extraction is attempted, or even if the first
// character on the stream is peeked at, and an exception
// is thrown during input, badbit should be set, otherwise
// if in_avail() returned -1, eofbit should be set, else
// the state should be good
if (-2 == l)
expect_state = std::ios_base::badbit;
else if (l < 0)
expect_state = std::ios_base::eofbit;
else
expect_state = std::ios_base::goodbit;
#else // if defined (_RWSTD_NO_EXCEPTIONS)
if (l < 0)
expect_state = std::ios_base::eofbit;
else
expect_state = std::ios_base::goodbit;
#endif // _RWSTD_NO_EXCEPTIONS
}
else {
// ...if the initial stream state is not good, failbit
// must be set
expect_state = states [i] | std::ios_base::failbit;
}
rw_assert (is.rdstate () == expect_state, 0, __LINE__,
"%{$FCALL}: rdstate() == %{Is}, got %{Is}; "
"extracted %u characters; "
"initial state = %{Is}, underflow %s at extraction %u",
expect_state, is.rdstate (), extracted,
states [i], err_type, k);
++iter;
}
/***********************************************************************/
template <class charT, class Traits>
void test_readsome (const charT*, const Traits*,
const char *cname, const char *tname)
{
memfun_info (__LINE__, cname, tname);
//////////////////////////////////////////////////////////////
// exercise 27.6.1.3, p1
const charT cbuf[] = { ' ', 'a', ' ', 'b', 'c', '\0' };
const unsigned cbuf_size = sizeof cbuf / sizeof *cbuf;
unsigned iter = 0; // iteration counter
// iterate over all possible settings of the stream state
for (unsigned i = 0; i != nstates; ++i) {
// call readsome(..., j) to extract j characters
for (unsigned j = 0; j != cbuf_size - 1; ++j) {
// have underflow() fail after the `k-th' extraction
for (unsigned k = 0; k != j + 1; ++k) {
// return `l' from showmanyc(); -2 will throw
for (int l = -4; l != int (k); ++l) {
// if (0 == m), underflow() will throw an exception
// at `k-th' extraction, otherwise the function will
// return EOF
for (unsigned m = 0; m != 2; ++m, ++iter) {
// prevent causing underflow() to fail by
// returning EOF when in_avail() promised
// it wouldn't (by returning a value
// greater than the number of extractions
// underflow() will allow to succeed)
if (1U == m && int (k) < l)
continue;
test_readsome (cbuf, (Traits*)0,
cbuf_size, i, j, k, l, m);
}
}
}
}
}
}
/***********************************************************************/
static int opt_char;
static int opt_wchar;
static int opt_char_traits;
static int opt_user_traits;
static int
run_test (int, char**)
{
// introduce char_traits into scope
using namespace std;
#undef TEST
#define TEST(CharT, Traits) \
test_readsome ((CharT*)0, (Traits*)0, #CharT, #Traits)
if (rw_note (0 <= opt_char && 0 <= opt_char_traits, 0, __LINE__,
"basic_istream<char, char_traits<char>>::readsome() "
"tests disabled"))
TEST (char, char_traits<char>);
if (rw_note (0 <= opt_char && 0 <= opt_user_traits, 0, __LINE__,
"basic_istream<char, UserTraits<char>>::readsome() "
"tests disabled"))
TEST (char, UserTraits<char>);
#ifndef _RWSTD_NO_WCHAR_T
if (rw_note (0 <= opt_wchar && 0 <= opt_char_traits, 0, __LINE__,
"basic_istream<wchar_t, char_traits<wchar_t>>::readsome() "
"tests disabled"))
TEST (wchar_t, char_traits<wchar_t>);
if (rw_note (0 <= opt_wchar && 0 <= opt_user_traits, 0, __LINE__,
"basic_istream<wchar_t, UserTraits<wchar_t>>::readsome() "
"tests 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.unformatted",
"readsome",
run_test,
"|-char~ "
"|-wchar_t~ "
"|-char_traits~ "
"|-UserTraits~ ",
&opt_char,
&opt_wchar,
&opt_char_traits,
&opt_user_traits,
(void*)0 /* sentinel */);
}

View File

@@ -0,0 +1,524 @@
/************************************************************************
*
* istream_sentry.cpp - test exercising basic_istream<charT>::sentry
*
* $Id: 27.istream.sentry.cpp 503938 2007-02-06 00:41:34Z 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 <istream>
#include <locale> // for ctype
#include <streambuf> // for streambuf
#include <rw_char.h> // for UserChar, UserTraits
#include <rw_printf.h> // for rw_printf()
#include <driver.h>
/************************************************************************
27.6.1.1.2 Class basic_istream::sentry [lib.istream::sentry]
namespace std {
template <class charT, class traits = char_traits<charT> >
class basic_istream<charT, traits>::sentry {
typedef traits traits_type;
bool ok_; // exposition only
public:
explicit
sentry (basic_istream<charT, traits>& is, bool noskipws = false);
~sentry ();
operator bool() const { return ok_; }
private:
sentry (const sentry&); // not defined
sentry& operator= (const sentry&); // not defined
};
}
-1- The class sentry defines a class that is responsible for doing
exception safe prefix and suffix operations.
explicit sentry(basic_istream<charT, traits>& is, bool noskipws = false);
-2- Effects: If is.good() is true, prepares for formatted or unformatted
input. First, if is.tie() is not a null pointer, the function calls
is.tie()<29>>flush() to synchronize the output sequence with any
associated external C stream. Except that this call can be suppressed
if the put area of is.tie() is empty. Further an implementation is
allowed to defer the call to flush until a call of
is->rdbuf()<29>>underflow occurs. If no such call occurs before the
sentry object is destroyed, the call to flush may be eliminated
entirely(279). If noskipws is zero and is.flags() & ios_base::skipws
is nonzero, the function extracts and discards each character as long
as the next available input character c is a whitespace character.
-3- Notes: The constructor explicit sentry(basic_istream<charT, traits>&
is, bool noskipws = false) uses the currently imbued locale in is,
to determine whether the next input character is whitespace or not.
-4- To decide if the character cis a whitespace character, the constructor
performs "as if" it executes the following code fragment:
const ctype<charT>& ctype = use_facet<ctype<charT> >(is.getloc());
if (ctype.is (ctype.space,c) != 0)
// c is a whitespace character.
-5- If, after any preparation is completed, is.good() is true,
ok_ != false otherwise, ok_ == false. During preparation, the
constructor may call setstate(failbit) (which may throw
ios_base::failure (27.4.4.3))(280)
__________________
279) This will be possible only in functions that are part of the
library. The semantics of the constructor used in user code is
as specified.
280) The sentry constructor and destructor can also perform additional
implementation-dependent operations.
-6- [Example: A typical implementation of the sentry constructor might
include code such as:
template <class charT, class traits = char_traits<charT> >
basic_istream<charT,traits>::sentry(
basic_istream<charT,traits>& is, bool noskipws = false) {
...
int_type c;
typedef ctype<charT> ctype_type;
const ctype_type& ctype = use_facet<ctype_type>(is.getloc());
while ((c = is.rdbuf()<29>>snextc()) != traits::eof()) {
if (ctype.is(ctype.space,c)==0) {
is.rdbuf()<29>>sputbackc (c);
break;
}
}
...
}
--end example]
~sentry();
-7- Effects: None.
operator bool() const;
-8- Effects: Returns ok_.
************************************************************************/
void
memfun_info (int line, const char *cname, const char *tname, const char *fname)
{
// format the ISTREAM and SENTRY environment variables w/o writing
// out any output
rw_fprintf (0,
"%{$ISTREAM!:@}",
"%{?}istream%{:}%{?}wistream"
"%{:}basic_istream<%s, %s>%{;}%{;}",
'c' == *cname && 'c' == *tname,
'w' == *cname && 'c' == *tname,
cname, tname);
rw_fprintf (0,
"%{$SENTRY!:@}",
"%{$ISTREAM}::sentry");
// pass fname through the "%{@}" directive to expand any embedded
// %{$XYZ} directives
rw_info (0, 0, line, "std::%{$SENTRY}::%{@}", fname);
}
/***********************************************************************/
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 (unsigned ref, charT white)
: Base (ref), ws_ (white) { }
// virtuals overridden below used by ctype<wchar_t>
// ctype<char> uses the table() member instead
/* 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);
}
/* virtual */ const charT*
do_is (const charT *from, const charT *to,
std::ctype_base::mask *m) const {
return Base::is (from, to, m);
}
/* virtual */ const charT*
do_scan_is (std::ctype_base::mask m,
const charT *from, const charT *to) const {
for (; from != to && !do_is (m, *from); ++from);
return from;
}
/* virtual */ const charT*
do_scan_not (std::ctype_base::mask m,
const charT *from, const charT *to) const {
for (; from != to && do_is (m, *from); ++from);
return from;
}
};
// specialized for ctype<char>
_RWSTD_SPECIALIZED_CLASS
Ctype<char>::Ctype (unsigned ref, char white)
: Base (table_, false, ref), ws_ (white)
{
for (unsigned 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;
}
template <class charT, class Traits>
struct Streambuf: std::basic_streambuf<charT, Traits>
{
typedef std::basic_streambuf<charT, Traits> Base;
int nsyncs_;
Streambuf (const charT *gbeg, const charT *gend)
: Base (), nsyncs_ (0) {
this->setg (_RWSTD_CONST_CAST (charT*, gbeg),
_RWSTD_CONST_CAST (charT*, gbeg),
_RWSTD_CONST_CAST (charT*, gend));
}
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 ();
}
};
template <class charT, class Traits>
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;
}
}
}
}
}
/***********************************************************************/
template <class charT, class Traits>
void test_ok (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, "operator bool () const");
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, p5:
// - 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
// = if, after any preparation is completed, is.good() is true,
// ok_ != false otherwise, ok_ == false.
unsigned iter = 0; // iteration counter
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);
const Sentry guard (is, 0 != j);
_RWSTD_UNUSED (guard);
const bool success =
is.good () && guard
|| !is.good () && !guard;
rw_assert (success, 0, __LINE__,
"%u. %{$SENTRY}"
"(%{$ISTREAM} &is, bool noskipws "
"= %d).operator bool() == %d; initial "
"is.state() = %{Is}, is.flags() & "
"ios::skipws = %d",
iter, j, is.good (),
states [i], k);
++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(what, charT, Traits) \
test_ ## what ((charT*)0, (Traits*)0, #charT, #Traits)
using namespace std;
if (rw_note (0 <= opt_char && 0 <= opt_char_traits, 0, __LINE__,
"istream::sentry tests disabled")) {
TEST (ctor, char, char_traits<char>);
TEST (ok, char, char_traits<char>);
}
if (rw_note (0 <= opt_char && 0 <= opt_user_traits, 0, __LINE__,
"basic_istream<char, UserTraits<char>::sentry "
"tests disabled")) {
TEST (ctor, char, UserTraits<char>);
TEST (ok, char, UserTraits<char>);
}
#ifndef _RWSTD_NO_WCHAR_T
if (rw_note (0 <= opt_wchar && 0 <= opt_char_traits, 0, __LINE__,
"wistream::sentry tests disabled")) {
TEST (ctor, wchar_t, char_traits<wchar_t>);
TEST (ok, wchar_t, char_traits<wchar_t>);
}
if (rw_note (0 <= opt_wchar && 0 <= opt_user_traits, 0, __LINE__,
"basic_istream<wchar_t, UserTraits<wchar_t>::sentry "
"tests disabled")) {
TEST (ctor, wchar_t, UserTraits<wchar_t>);
TEST (ok, 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.sentry",
0 /* no comment */,
run_test,
"|-char~ "
"|-wchar_t~ "
"|-char_traits~ "
"|-UserTraits~ ",
&opt_char,
&opt_wchar,
&opt_char_traits,
&opt_user_traits,
(void*)0 /* sentinel */);
}

View File

@@ -0,0 +1,802 @@
/************************************************************************
*
* 27.istream.unformatted.get.cpp - test exercising overloads of
* basic_istream::get()
*
* $Id: 27.istream.unformatted.get.cpp 590052 2007-10-30 12:44:14Z faridz $
*
***************************************************************************
*
* 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 <fstream>
#include <istream>
#include <sstream>
#include <cstddef> // for size_t
#include <driver.h> // for rw_test(), ...
#include <rw_char.h> // for UserTraits
#include <rw_streambuf.h> // for MyStreambuf
/***********************************************************************/
#define Bad std::ios_base::badbit
#define Eof std::ios_base::eofbit
#define Fail std::ios_base::failbit
#define Good std::ios_base::goodbit
template <class charT, class Traits>
void
check_failure (const MyStreambuf<charT, Traits>& sb,
const char* cname,
int lineno,
const char* fun,
std::basic_istream<charT, Traits>& strm,
int gcount,
int nexpect,
int rdstate,
int exceptions,
int caught)
{
static const char* const exnames[] = {
"none", "std::ios_base::failure",
"streambuf_exception", "unknown exception"
};
const char* const caught_what = exnames [caught];
// verify that stream is in the expected state
rw_assert (strm.rdstate () == rdstate, 0, lineno,
"line %d: basic_istream<%s>::%s; "
"rdstate () == %{Is}, got %{Is}",
__LINE__, cname, fun, rdstate, strm.rdstate ());
if (sb.throw_set_ && sb.ncalls (sb.threw_) == sb.fail_when_) {
// verify that the same exception (and not ios_base::failure)
// as the one thrown from basic_filebuf has been propagated
// and caught when badbit is set in exceptions, and that no
// exception has been thrown if exceptions is clear
if (exceptions & Bad && caught != 2) {
rw_assert (false, 0, lineno,
"line %d: basic_istream<%s>::%s failed "
"to propagate an exception thrown "
"by basic_filebuf; caught %s instead",
__LINE__, cname, fun,
caught_what);
}
else if (!(exceptions & Bad) && caught) {
rw_assert (false, 0, lineno,
"line %d: basic_istream<%s>::%s propagated "
"an exception thrown by basic_filebuf when "
"ios_base::badbit is clear in exceptions",
__LINE__, cname, fun);
}
// verify that the original gcount of 0 was unaffected
// (for non-array forms of unformatted input functions)
// or that it increased exactly `fail_when_'
const int actual = strm.gcount () - gcount;
rw_assert (!actual || actual == sb.fail_when_ - 1, 0, lineno,
"line %d: basic_istream<%s>::%s changed "
"gcount () from %d to %d after a failure; "
"either no change from 0 expected, or "
"an increase to %d from 0 expected",
__LINE__, cname, fun,
gcount, strm.gcount (), sb.fail_when_ - 1);
}
else {
// verify that ios_base::failure has been thrown (and caught)
// if badbit is set in exceptions
rw_assert (!(exceptions & strm.rdstate ()) || caught == 1,
0, lineno,
"line %d: basic_istream<%s>::%s set %{Is} "
"but failed to throw ios_base::failure "
"when the same bit is set in exceptions",
__LINE__, cname, fun, rdstate);
// verify that gcount has the expected value
const int actual = strm.gcount () - gcount;
rw_assert (nexpect == actual, 0, lineno,
"line %d: basic_istream<%s>::%s changed "
"gcount () from %d to %d after a successful "
"extraction; a change from 0 to %d expected",
__LINE__, cname, fun,
gcount, strm.gcount (), nexpect);
}
}
/***********************************************************************/
#define TRY_GET(expr) \
try { \
expr; \
} \
catch (const std::ios_base::failure&) { \
caught = 1; \
} \
catch (Exception& e) { \
caught = ex_stream == e.id_ ? 2 : 3; \
} \
catch (...) { \
caught = 3; \
} (void)0
/***********************************************************************/
// 27.6.1.3 Unformatted input functions [lib.istream.unformatted]
//
// -1- Each unformatted input function begins execution by constructing
// an object of class sentry with the default argument noskipws
// (second) argument true. If the sentry object returns true, when
// converted to a value of type bool, the function endeavors to
// obtain the requested input. If an exception is thrown during
// input then ios::badbit is turned on284) in *this?s error state.
// If (exception() & badbit) != 0 then the exception is rethrown.
// It also counts the number of characters extracted. If no exception
// has been thrown it ends by storing the count in a member object
// and returning the value specified. In any event the sentry object
// is destroyed before leaving the unformatted input function.
template <class charT, class Traits>
void
test_get_void (charT, const char *cname,
const Traits*, int lineno,
const char *str,
std::size_t strsize,
int ival,
int rdstate,
int exceptions,
int failure,
int fail_when)
{
// int_type get();
// -3- Effects: Extracts a character c, if one is available.
// Otherwise, the function calls setstate(failbit),
// which may throw ios_base::failure (27.4.4.3),
// -4- Returns: c if available, otherwise traits::eof().
typedef MyStreambuf<charT, Traits> Streambuf;
typedef std::basic_istream<charT, Traits> Istream;
typedef typename Istream::int_type int_type;
const int_type val = int_type (ival);
// create a test streambuf object initialized with `str'
Streambuf sb (str, strsize, failure, fail_when);
Istream strm (&sb);
strm.exceptions (std::ios_base::iostate (exceptions));
const std::streamsize gcount = strm.gcount ();
int_type got = Traits::eof ();
int caught = 0;
TRY_GET (got = strm.get ());
check_failure (sb, cname, lineno, "get()", strm, gcount, !rdstate,
rdstate, exceptions, caught);
// verify that the extracted value is the one expected
if (!sb.throw_set_ && !caught && val != got) {
const charT cval = Traits::to_char_type (val);
const charT cgot = Traits::to_char_type (got);
rw_assert (false, __FILE__, lineno,
"line %d: basic_istream<%s>::get () == %{#lc}, got %{#lc}",
__LINE__, cname, cval, cgot);
}
rw_assert (val == Traits::eof () || !(gcount || 1 != strm.gcount ()),
0, lineno,
"line %d: basic_istream<%s>::get () changed "
"gcount () from %d to %d after a successful "
"extraction; 0 to 1 expected",
__LINE__, cname,
gcount, strm.gcount ());
}
/***********************************************************************/
template <class charT>
void test_get_void (charT, const char *cname)
{
#define T charT (), cname, (UserTraits<charT>*)0, __LINE__
#define TEST test_get_void
rw_info (0, 0, 0, "27.6.1.3, p3 - std::basic_istream<%s>::get ()",
cname);
typename UserTraits<charT>::int_type &eof =
UserTraits<charT>::eof_;
eof = ~0;
TEST (T, "", 0, eof, Eof | Fail, Good, 0, -1);
TEST (T, "", 1, '\0', Good, Good, 0, -1);
TEST (T, "a", 1, 'a', Good, Good, 0, -1);
TEST (T, " b", 2, ' ', Good, Good, 0, -1);
TEST (T, "\x80", 1, 0x80, Good, Good, 0, -1);
TEST (T, "\xff ", 2, 0xff, Good, Good, 0, -1);
TEST (T, "c", 1, eof, Eof | Fail, Good, Underflow, 1);
TEST (T, "d", 1, eof, Bad, Good, Underflow | Throw, 1);
eof = 256;
TEST (T, "", 0, eof, Eof | Fail, Good, 0, 0);
TEST (T, "f", 1, 'f', Good, Good, 0, 0);
TEST (T, "g", 1, eof, Eof | Fail, Good, Underflow, 1);
TEST (T, "h", 1, eof, Bad, Good, Underflow | Throw, 1);
eof = '\0';
TEST (T, "\0", 1, eof, Eof | Fail, Good, 0, -1);
TEST (T, "\1", 1, eof, Eof | Fail, Good, Underflow, 1);
TEST (T, "\2", 1, eof, Bad, Good, Underflow | Throw, 1);
}
/***********************************************************************/
template <class charT, class Traits>
void test_get_char (charT, const char* cname,
const Traits*, int lineno,
const char *str,
std::size_t strsize,
char initval,
char expectval,
int rdstate,
int exceptions,
int failure,
int fail_when)
{
// basic_istream<charT, Traits>& get (char_type&);
// -5- Effects: Extracts a character, if one is available,
// and assigns it to c.(285) Otherwise, the function calls
// setstate(failbit) (which may throw ios_base::failure
// (27.4.4.3)).
// -6- Returns: *this.
// ---
// 285) Note that this function is not overloaded on types signed
// charand unsigned char.
typedef MyStreambuf<charT, Traits> Streambuf;
typedef std::basic_istream<charT, Traits> Istream;
typedef typename Istream::int_type int_type;
// create a test streambuf object initialized with `str'
Streambuf sb (str, strsize, failure, fail_when);
Istream strm (&sb);
strm.exceptions (std::ios_base::iostate (exceptions));
const std::streamsize gcount = strm.gcount ();
typedef unsigned char UChar;
charT got = charT (UChar (initval));
const charT val = charT (UChar (expectval));
int caught = 0;
TRY_GET (strm.get (got));
check_failure (sb, cname, lineno, "get(char_type&)", strm,
gcount, !rdstate, rdstate, exceptions, caught);
// verify that the extracted value is the one expected
rw_assert (sb.throw_set_ || caught || Traits::eq (val, got), 0, lineno,
"line %d: basic_istream<%s>::get (char_type& = %{#lc}),"
" expected %{#lc}", __LINE__, cname, got, val);
rw_assert (rdstate || !(gcount || 1 != strm.gcount ()), 0, lineno,
"line %d: basic_istream<%s>::get (char_type&) "
"changed gcount () from %d to %d after a successful "
"extraction; 0 to 1 expected",
__LINE__, cname,
gcount, strm.gcount ());
}
/***********************************************************************/
template <class charT>
void test_get_char (charT, const char *cname)
{
#undef T
#undef TEST
#define T charT (), cname, (UserTraits<charT>*)0, __LINE__
#define TEST test_get_char
rw_info (0, 0, 0,
"27.6.1.3, p5 - std::basic_istream<%s>::get (char_type&)",
cname);
typename UserTraits<charT>::int_type &eof =
UserTraits<charT>::eof_;
eof = ~0;
// +- initial stream buffer contents (will be widened)
// | +- the length of the buffer contents in chars
// | | +- initial value of get(char_type&) argument
// | | | +- expected value of argument on return
// | | | | +- expected stream state on return
// | | | | | +- stream exceptions
// | | | | | | +- force failure
// | | | | | | | +- when to fail
// | | | | | | | |
// v v v v v v v v
TEST (T, "", 0, '\0', '\0', Eof | Fail, Good, 0, -1);
TEST (T, "", 1, '\1', '\0', Good, Good, 0, -1);
TEST (T, "1", 1, '\2', '1', Good, Good, 0, -1);
TEST (T, "2 ", 2, '\3', '2', Good, Good, 0, -1);
TEST (T, " 3", 2, '\4', ' ', Good, Good, 0, -1);
TEST (T, "4", 1, '\5', '\5', Eof | Fail, Good, Underflow, 1);
TEST (T, "5", 1, '\6', '\6', Bad, Good, Underflow | Throw, 1);
TEST (T, "6", 1, '\7', '\6', Eof | Fail, Eof, Underflow, 1);
TEST (T, "7", 1, 'x', 'x', Eof | Fail, Fail, Underflow, 1);
TEST (T, "8", 1, 'y', 'y', Eof | Fail, Eof | Fail, Underflow, 1);
TEST (T, "9", 1, 'z', 'z', Eof | Fail, Eof | Fail | Bad, Underflow, 1);
TEST (T, "A", 1, 'a', 'a', Bad, Bad, Underflow | Throw, 1);
}
/***********************************************************************/
#define MAXCHARS (4096U * 4U)
template <class charT, class Traits>
void test_get_char_array (charT, const char* cname,
const Traits*,
int lineno,
const char *str,
std::size_t strsize,
int nread,
int idelim,
int nexpect,
int rdstate,
int exceptions,
int failure,
int fail_when)
{
// basic_istream<charT, traits>&
// get(char_type* s, streamsize n, char_type delim);
//
// -7- Effects: Extracts characters and stores them into successive
// locations of an array whose first element is designated by s.
// 286) Characters are extracted and stored until any of the
// following occurs:
// - (n - 1) characters are stored;
// - end-of-file occurs on the input sequence (in which case
// the function calls setstate(eofbit));
// - (c == delim) for the next available input character c
// (in which case cis not extracted).
//
// -8- If the function stores no characters, it calls setstate(failbit)
// (which may throw ios_base::failure (27.4.4.3)). In any case, it
// then stores a null character into the next successive location
// of the array.
//
// -9- Returns: *this.
// basic_istream<charT,traits>&
// get(char_type* s, streamsize n);
//
// -10- Effects: Calls get(s, n, widen('\n')).
// -11- Returns: Value returned by the call.
typedef MyStreambuf<charT, Traits> Streambuf;
typedef std::basic_istream<charT, Traits> Istream;
typedef typename Istream::int_type int_type;
const int_type delim = int_type (idelim);
// create a test streambuf object initialized with `str'
Streambuf sb (str, strsize, failure, fail_when);
Istream strm (&sb);
strm.exceptions (std::ios_base::iostate (exceptions));
const std::streamsize gcount = strm.gcount ();
typedef unsigned char UChar;
int caught = 0;
charT got [MAXCHARS + 1];
Traits::assign (got, sizeof got / sizeof *got, charT ('\xfe'));
const char *fun;
if (delim != Traits::eof ()) {
fun = "get(char_type*, streamsize, char_type)";
TRY_GET (strm.get (got, std::streamsize (nread), delim));
}
else {
fun = "get(char_type*, streamsize)";
TRY_GET (strm.get (got, std::streamsize (nread)));
}
check_failure (sb, cname, lineno, fun, strm, gcount, nexpect,
rdstate, exceptions, caught);
// verify that number and values of the extracted characters
// matches the expected number and values
rw_assert (strm.gcount () == nexpect, 0, lineno,
"line %d: basic_istream<%s>::get (char_type*, "
"streamsize = %d).gcount () == %d, got %d",
__LINE__, cname, nread, nexpect, strm.gcount ());
rw_assert (1 < nread || Traits::eq (got [0], charT ()), 0, lineno,
"line %d: basic_istream<%s>::get (char_type *s "
"= %{*Ac}, streamsize = %d); s[0] == '\\0', got %{#lc}",
__LINE__, cname, int (sizeof *got), got, nread, *got);
rw_assert (!Traits::compare (sb.buf_, got, std::size_t (nexpect)),
0, lineno,
"line %d: basic_istream<%s>::get (char_type* "
"= %{*Ac}, streamsize = %d) data mismatch",
__LINE__, cname, int (sizeof *got), got, nread);
}
/***********************************************************************/
template <class charT>
void test_get_char_array (charT, const char *cname)
{
#undef T
#undef TEST
#define T charT (), cname, (UserTraits<charT>*)0, __LINE__
#define TEST test_get_char_array
rw_info (0, 0, 0, "27.6.1.3, p5 - std::basic_istream<%s>"
"::get (char_type*, streamsize)", cname);
typename UserTraits<charT>::int_type &eof =
UserTraits<charT>::eof_;
eof = ~0;
// +- initial stream buffer contents (will be widened)
// | +- the length of the buffer contents in chars
// | | +- number of characters (2nd argument to get())
// | | +- delimiter (3rd argument to get() or eof)
// | | | | +- expected number of extracted characters
// | | | | | +- expected stream state on return
// | | | | | | +- stream exceptions
// | | | | | | | +- force failure
// | | | | | | | | +- when to fail
// | | | | | | | | |
// v v v v v v v v v
TEST (T, "", 0, 0, eof, 0, Fail, Good, 0, -1);
TEST (T, "\0", 1, 1, eof, 0, Fail, Good, 0, -1);
TEST (T, "1", 1, 2, eof, 1, Good, Good, 0, -1);
TEST (T, "2", 1, 3, eof, 1, Eof, Good, 0, -1);
TEST (T, "23", 2, 3, eof, 2, Good, Good, 0, -1);
TEST (T, "34", 2, 4, eof, 2, Eof, Good, 0, -1);
TEST (T, "4\n", 2, 3, eof, 1, Good, Good, 0, -1);
TEST (T, "56\n", 3, 3, eof, 2, Good, Good, 0, -1);
TEST (T, "67\n", 3, 4, eof, 2, Good, Good, 0, -1);
// exercise the behavior on underflow() failure indicated
// by returning traits_type::eof()
TEST (T, "78\n9", 4, 4, eof, 0, Eof | Fail, Good, Underflow, 1);
TEST (T, "78901", 5, 5, eof, 0, Eof | Fail, Eof, Underflow, 1);
TEST (T, "78902", 5, 5, eof, 0, Eof | Fail, Fail, Underflow, 1);
TEST (T, "78803", 5, 5, eof, 0, Eof | Fail, Eof | Fail, Underflow, 1);
TEST (T, "89\na", 4, 4, eof, 1, Eof, Good, Underflow, 2);
TEST (T, "9a\nb", 4, 4, eof, 2, Eof, Good, Underflow, 3);
TEST (T, "ab\nc", 4, 4, eof, 2, Good, Good, Underflow, 4);
// exercise the behavior on underflow() failure caused
// by throwing an exception
TEST (T, "bc\nd", 4, 4, eof, 0, Bad, Good, Underflow | Throw, 1);
TEST (T, "cd\ne", 4, 4, eof, 1, Bad, Good, Underflow | Throw, 2);
TEST (T, "def\n", 4, 4, eof, 2, Bad, Good, Underflow | Throw, 3);
TEST (T, "efg\n", 4, 4, eof, 2, Bad, Bad, Underflow | Throw, 3);
TEST (T, "fgh\n", 4, 4, eof, 3, Good, Bad, Underflow | Throw, 4);
TEST (T, "ghij", 4, 4, eof, 3, Good, Bad, Underflow | Throw, 4);
TEST (T, "hijk", 4, 5, eof, 3, Bad, Bad, Underflow | Throw, 4);
const std::streamsize N = std::streamsize (MAXCHARS);
char *buf = new char [N];
for (std::streamsize i = 0; i != N; ++i) {
buf [i] = char (i);
}
// set the maximum number of characters in the pending input
// sequence to be greater than the default 1 to allow get()
// not to have to call underflow() on every iteration and
// to exercise any/all branches in the function
MyStreambuf<charT, UserTraits<charT> >::in_pending_ = N / 33;
TEST (T, "12345", 5, 4, eof, 3, Good, Good, 0, -1);
TEST (T, "12346", 5, 5, eof, 4, Good, Good, 0, -1);
TEST (T, "12347", 5, 6, eof, 5, Good, Good, 0, -1);
TEST (T, "12348", 5, 7, eof, 5, Eof, Good, 0, -1);
for (std::streamsize i = 0; i < N; i += 256) {
TEST (T, buf, N, N, eof, '\n' + i, Good, Good, 0, -1);
buf ['\n' + i] = '\0';
}
rw_info (0, 0, 0, "27.6.1.3, p5 - std::basic_istream<%s>"
"::get (char_type*, streamsize, char_type)", cname);
TEST (T, "", 0, 0, '\0', 0, Fail, Good, 0, -1);
TEST (T, "", 1, 1, '\0', 0, Fail, Good, 0, -1);
TEST (T, "a", 1, 2, '\0', 1, Good, Good, 0, -1);
TEST (T, "bc", 2, 2, 'c', 1, Good, Good, 0, -1);
TEST (T, "cd", 2, 3, 'd', 1, Good, Good, 0, -1);
TEST (T, "de", 2, 3, 'd', 0, Fail, Good, 0, -1);
}
/***********************************************************************/
template <class charT, class Traits>
void test_get_streambuf (charT, const char* cname,
const Traits*,
int lineno,
const char *str,
std::size_t strsize,
int idelim,
int nexpect,
int rdstate,
int exceptions,
int failure,
int fail_when)
{
typedef MyStreambuf<charT, Traits> Streambuf;
typedef std::basic_istream<charT, Traits> Istream;
typedef typename Istream::int_type int_type;
const int_type delim = int_type (idelim);
int in_failure, in_fail_when;
int out_failure, out_fail_when;
switch (failure & ~Throw) {
case Xsgetn: case Underflow: case Uflow:
in_failure = failure;
in_fail_when = fail_when;
out_failure = 0;
out_fail_when = 0;
break;
case Overflow: case Xsputn:
in_failure = 0;
in_fail_when = 0;
out_failure = failure;
out_fail_when = fail_when;
break;
default:
in_failure = failure;
in_fail_when = fail_when;
out_failure = failure;
out_fail_when = fail_when;
}
// create a test streambuf object initialized with `str'
Streambuf inbuf (str, strsize, in_failure, in_fail_when);
Istream strm (&inbuf);
strm.exceptions (std::ios_base::iostate (exceptions));
const std::streamsize gcount = strm.gcount ();
typedef unsigned char UChar;
int caught = 0;
Streambuf outbuf (strsize, out_failure, out_fail_when);
const char *fun;
if (delim != Traits::eof ()) {
fun = "get(basic_streambuf<char_type, traits_type>&, char_type)";
TRY_GET (strm.get (outbuf, delim));
}
else {
fun = "get(basic_streambuf<char_type, traits_type>&)";
TRY_GET (strm.get (outbuf));
}
check_failure (inbuf, cname, lineno, fun, strm, gcount, nexpect,
rdstate, exceptions, caught);
// verify that number and values of the extracted characters
// matches the expected number and values
rw_assert (strm.gcount () == nexpect, 0, lineno,
"line %d: basic_istream<%s>::get (basic_streambuf"
"<char_type, traits_type>*).gcount () == %d, got %d",
__LINE__, cname, nexpect, strm.gcount ());
rw_assert (!Traits::compare (inbuf.buf_, outbuf.buf_,
std::size_t (nexpect)), 0, lineno,
"line %d: basic_istream<%s>::get (basic_streambuf"
"<char_type, traits_type>*) data mismatch",
__LINE__, cname);
}
/***********************************************************************/
template <class charT>
void test_get_streambuf (charT, const char *cname)
{
#undef T
#undef TEST
#define T charT (), cname, (UserTraits<charT>*)0, __LINE__
#define TEST test_get_streambuf
rw_info (0, 0, 0, "27.6.1.3, p12 - std::basic_istream<%s>"
"::get (basic_streambuf<char_type, traits_type>*, char_type)",
cname);
typename UserTraits<charT>::int_type &eof =
UserTraits<charT>::eof_;
eof = ~0;
// set the maximum number of characters in the pending input
// sequence to 1 to force a call to underflow() for each
// character
MyStreambuf<charT, UserTraits<charT> >::in_pending_ = 1;
// basic_istream<charT, traits>&
// get (basic_streambuf<charT, traits> &sb, char_type delim);
//
// -12- Effects: Extracts characters and inserts them in the output
// sequence controlled by sb. Characters are extracted and
// inserted until any of the following occurs:
// - end-of-file occurs on the input sequence;
// - inserting in the output sequence fails (in which case the
// character to be inserted is not extracted);
// - (c == delim) for the next available input character c
// (in which case cis not extracted);
// - an exception occurs (in which case, the exception is caught
// but not rethrown).
// -13- If the function inserts no characters, it calls
// setstate(failbit), which may throw ios_base::failure (27.4.4.3).
// -14- Returns: *this.
TEST (T, "", 0, 'x', 0, Eof | Fail, Good, 0, 0);
TEST (T, "\0", 1, 'y', 1, Eof, Good, 0, 0);
TEST (T, "ab", 2, 'z', 2, Eof, Good, 0, 0);
TEST (T, "abc", 3, '\0', 3, Eof, Good, 0, 0);
TEST (T, "b\0c", 3, '\0', 1, Good, Good, 0, 0);
TEST (T, "cd\0e", 4, '\0', 2, Good, Good, 0, 0);
TEST (T, "def\0", 4, '\0', 3, Good, Good, 0, 0);
TEST (T, "efgh", 4, 'f', 0, Eof | Fail, Good, Underflow, 1);
TEST (T, "fghi", 4, 'g', 0, Eof | Fail, Eof, Underflow, 1);
TEST (T, "ghij", 4, 'h', 0, Eof | Fail, Fail, Underflow, 1);
TEST (T, "hijk", 4, 'i', 0, Eof | Fail, Eof | Fail, Underflow, 1);
TEST (T, "ijkl", 4, 'k', 1, Eof, Good, Underflow, 2);
TEST (T, "jklm", 4, 'm', 2, Eof, Good, Underflow, 3);
TEST (T, "klmn", 4, 'n', 2, Bad, Good, Underflow | Throw, 3);
TEST (T, "lmno", 4, 'o', 2, Bad, Bad, Underflow | Throw, 3);
TEST (T, "EFGH", 4, 'F', 0, Fail, Good, Overflow, 1);
TEST (T, "FGHI", 4, 'G', 0, Fail, Eof, Overflow, 1);
TEST (T, "GHIJ", 4, 'H', 0, Fail, Fail, Overflow, 1);
TEST (T, "HIJK", 4, 'I', 0, Fail, Eof | Fail, Overflow, 1);
TEST (T, "IJKL", 4, 'K', 1, Fail, Good, Overflow, 2);
TEST (T, "JKLM", 4, 'M', 2, Fail, Good, Overflow, 3);
TEST (T, "KLMN", 4, 'N', 2, Fail, Good, Overflow | Throw, 3);
TEST (T, "LMNO", 4, 'O', 2, Fail, Bad, Overflow | Throw, 3);
rw_info (0, 0, 0, "27.6.1.3, p15 - std::basic_istream<%s>"
"::get (basic_streambuf<char_type, traits_type>&)", cname);
TEST (T, "", 0, eof, 0, Eof | Fail, Good, 0, 0);
TEST (T, "\n", 1, eof, 0, Fail, Good, 0, 0);
TEST (T, "a\n", 2, eof, 1, Good, Good, 0, 0);
TEST (T, "ab\n", 3, eof, 2, Good, Good, 0, 0);
}
/***********************************************************************/
static int rw_opt_no_get_void;
static int rw_opt_no_get_char;
static int rw_opt_no_get_char_array;
static int rw_opt_no_get_streambuf;
static int
run_test (int, char**)
{
#undef TEST
#define TEST(T, arg) \
if (rw_opt_no_get_ ## arg) \
rw_note (0, 0, 0, \
"basic_istream::get(%s) test disabled", #arg); \
else \
test_get_ ## arg (T (), #T)
TEST (char, void);
TEST (char, char);
TEST (char, char_array);
TEST (char, streambuf);
#ifndef _RWSTD_NO_WCHAR_T
TEST (wchar_t, void);
TEST (wchar_t, char);
TEST (wchar_t, char_array);
TEST (wchar_t, streambuf);
#endif // _RWSTD_NO_WCHAR_T
return 0;
}
/***********************************************************************/
int main (int argc, char *argv[])
{
return rw_test (argc, argv, __FILE__,
"lib.istream.unformatted",
"overloads of get() member function",
run_test,
"|-no-get-void#"
"|-no-get-char#"
"|-no-get-char_array#"
"|-no-get-streambuf#",
&rw_opt_no_get_void,
&rw_opt_no_get_char,
&rw_opt_no_get_char_array,
&rw_opt_no_get_streambuf,
0);
}

View File

@@ -0,0 +1,453 @@
/***************************************************************************
*
* 27.objects.cpp - test exercising lib.iostream.objects
*
* $Id: 27.objects.cpp 648752 2008-04-16 17:01:56Z faridz $
*
***************************************************************************
*
* 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 2000-2008 Rogue Wave Software, Inc.
*
**************************************************************************/
#include <driver.h>
// If the following macro is defined, then new header provides
// an implementation for operator new [] & delete []; undef them here
// so that the test can provide its own implementation for these operators
#undef _RWSTD_NO_OPERATOR_NEW_ARRAY
#undef _RWSTD_NO_OPERATOR_DELETE_ARRAY
#if defined (__IBMCPP__) && !defined (_RWSTD_NO_IMPLICIT_INCLUSION)
// disable implicit inclusion to work around
// a limitation in IBM VisualAge 5.0.2.0 (PR #26959)
# define _RWSTD_NO_IMPLICIT_INCLUSION
#endif
#if !defined (_MSC_VER) || _MSC_VER > 1300
// prevent out-of-line template definitions in .cc files from being
// explicitly #included during the processing of library headers (faster
// compilation) assumes that the test doesn't instantiate those templates
// on types other than those they were explcitly instantiated on (will
// have no effect if explicit instantiation is disabled or unsupported)
# define _RWSTD_NO_TEMPLATE_DEFINITIONS
#endif // !defined (_MSC_VER) || _MSC_VER > 1300
struct LifetimeChecker
{
LifetimeChecker ();
~LifetimeChecker ();
} lifetime_check;
#if defined (_WIN32) | defined (_WIN64)
// bring in <windows.h> as a compilation test to exercise
// any potential collisions with our declarations
# include <windows.h>
#endif
// include <iostream> *after* the definition of the global
// lifetime_checker object to exercise initialization and
// lifetime dependencies
#include <iostream> // for cin, cout, ...
#include <cstdlib> // for free(), malloc()
// make sure using declarations work (the test doesn't actually exploit
// the fact that the names are introduced into the global namespace)
_USING (std::cin);
_USING (std::cout);
_USING (std::cerr);
_USING (std::clog);
#ifndef _RWSTD_NO_WCHAR_T
_USING (std::wcin);
_USING (std::wcout);
_USING (std::wcerr);
_USING (std::wclog);
#endif // _RWSTD_NO_WCHAR_T
/**************************************************************************/
int init_new_calls; // number of calls to operator new during initialization
int init_delete_calls; // and operator delete
int new_calls; // total number of calls to operator new
int delete_calls; // and operator delete
int rw_opt_no_global_dtors; // for --no-global-dtors
int rw_opt_no_replacement_new; // for --no-replacement-new
int rw_opt_no_replacement_delete; // for --no-replacement-delete
/**************************************************************************/
LifetimeChecker::LifetimeChecker ()
{
// iostreams not yet initialized here
// <iostream> must be included before the definition of any
// global object whose ctor uses any of the standard objects
}
LifetimeChecker::~LifetimeChecker ()
{
if (rw_opt_no_global_dtors) {
rw_note (0, 0, __LINE__, "test of global dtors disabled");
}
else {
// objects must not be destroyed during program lifetime
// try to use them in the destructor of a global object...
std::cout << "[output from the dtor of a global object]";
std::cout << "[cout]";
std::cerr << "[cerr]";
std::clog << "[clog]";
#ifndef _RWSTD_NO_WCHAR_T
std::wcout << "[wcout]";
std::wcerr << "[wcerr]";
std::wclog << "[wclog]";
#endif // _RWSTD_NO_WCHAR_T
}
}
/**************************************************************************/
template <class charT>
void do_test (charT)
{
rw_info (0, 0, 0, "checking whether objects are initialized");
// objects must exist
rw_assert ( 0 != &std::cin && 0 != &std::cout
&& 0 != &std::cerr && 0 != &std::clog,
0, __LINE__, "std::cin, cout, cerr, or clog address 0");
rw_info (0, 0, __LINE__, "checking tied stream objects");
int new_0 = new_calls;
// exercise 27.3.1, p2
rw_assert (&std::cout == std::cin.tie (&std::cout), 0, __LINE__,
"&std::cout == std::cin.tie (&std::cout)");
rw_assert (0 == std::cout.tie (), 0, __LINE__,
"0 == std::cout.tie ()");
rw_assert (0 == std::cerr.tie (), 0, __LINE__,
"0 == std::cerr.tie ()");
rw_assert (0 == std::clog.tie (), 0, __LINE__,
"0 == std::clog.tie ()");
rw_assert (0 == new_calls - new_0, 0, __LINE__,
"unexpected dynamic memory allocation");
rw_info (0, 0, __LINE__, "checking for std::ios_base::unitbuf in flags");
new_0 = new_calls;
// exercise 27.3.1, p3
rw_assert (!(std::ios::unitbuf & std::cout.flags ()), 0, __LINE__,
"std::ios::unitbuf & std::cout.flags ()");
// exercise 27.3.1, p5
rw_assert (!!(std::ios::unitbuf & std::cerr.flags ()), 0, __LINE__,
"std::ios::unitbuf & std::cerr.flags ()");
// exercise 27.3.1, p6
rw_assert (!(std::ios::unitbuf & std::clog.flags ()), 0, __LINE__,
"std::ios::unitbuf & std::clog.flags ()");
rw_assert (0 == new_calls - new_0, 0, __LINE__,
"unexpected dynamic memory allocation");
#ifndef _RWSTD_NO_WCHAR_T
rw_assert ( 0 != &std::wcin && 0 != &std::wcout
&& 0 != &std::wcerr && 0 != &std::wclog,
0, __LINE__, "std::wcin, wcout, wcerr, or wclog address 0");
new_0 = new_calls;
// exercise 27.3.2, p2
rw_assert (&std::wcout == std::wcin.tie (&std::wcout), 0, __LINE__,
"&std::wcout == std::wcin.tie (&std::wcout)");
rw_assert (0 == std::wcout.tie (), 0, __LINE__,
"0 == std::wcout.tie ()");
rw_assert (0 == std::wcerr.tie (), 0, __LINE__,
"0 == std::wcerr.tie ()");
rw_assert (0 == std::wclog.tie (), 0, __LINE__,
"0 == std::wclog.tie ()");
rw_assert (0 == new_calls - new_0, 0, __LINE__,
"unexpected dynamic memory allocation");
new_0 = new_calls;
// exercise 27.3.2, p3
rw_assert (!(std::wios::unitbuf & std::wcout.flags ()), 0, __LINE__,
"std::wios::unitbuf & std::wcout.flags ()");
// exercise 27.3.2, p5
rw_assert (!!(std::wios::unitbuf & std::wcerr.flags ()), 0, __LINE__,
"std::wios::unitbuf & std::wcerr.flags ()");
// exercise 27.3.2, p6
rw_assert (!(std::wios::unitbuf & std::wclog.flags ()), 0, __LINE__,
"std::wios::unitbuf & std::wclog.flags ()");
rw_assert (0 == new_calls - new_0, 0, __LINE__,
"unexpected dynamic memory allocation");
#endif // _RWSTD_NO_WCHAR_T
std::cout << 0.0;
std::cerr << 0.0;
std::clog << 0.0;
#ifndef _RWSTD_NO_WCHAR_T
std::wcout << 0.0;
std::wcerr << 0.0;
std::wclog << 0.0;
#endif // _RWSTD_NO_WCHAR_T
std::cout << std::endl;
rw_info (0, 0, __LINE__, "exercising the ability to tie each stream "
"to itself without causing a deadlock");
std::cout.tie (&std::cout);
std::cout << std::cout.tie () << ' ';
std::cerr.tie (&std::cerr);
std::cerr << std::cerr.tie () << ' ';
std::clog.tie (&std::clog);
std::clog << std::clog.tie () << ' ';
#ifndef _RWSTD_NO_WCHAR_T
std::wcout.tie (&std::wcout);
std::wcout << std::wcout.tie () << ' ';
std::wcerr.tie (&std::wcerr);
std::wcerr << std::wcerr.tie () << ' ';
std::wclog.tie (&std::wclog);
std::wclog << std::wclog.tie () << ' ';
#endif // _RWSTD_NO_WCHAR_T
rw_info (0, 0, __LINE__, "exercising the ability to tie stream objects "
"together without causing a deadlock");
std::cout.tie (&std::cerr);
std::cout << std::cout.tie () << ' ';
std::cerr.tie (&std::cout);
std::cerr << std::cerr.tie () << ' ';
std::clog.tie (&std::cout);
std::clog << std::clog.tie () << ' ';
// untie all streams to free any memory dynamically
// allocated by calling tie (p) with (p != 0)
std::cin.tie (0);
std::cout.tie (0);
std::cerr.tie (0);
std::clog.tie (0);
#ifndef _RWSTD_NO_WCHAR_T
std::wcout.tie (&std::wcerr);
std::wcout << std::wcout.tie () << ' ';
std::wcerr.tie (&std::wcout);
std::wcerr << std::wcerr.tie () << ' ';
std::wclog.tie (&std::wcout);
std::wclog << std::wclog.tie () << ' ';
// untie all streams to free any memory dynamically
// allocated by calling tie (p) with (p != 0)
std::wcin.tie (0);
std::wcout.tie (0);
std::wcerr.tie (0);
std::wclog.tie (0);
#endif // _RWSTD_NO_WCHAR_T
std::cout << std::endl;
}
/**************************************************************************/
static int
run_test (int, char*[])
{
const int new_0 = new_calls;
const int delete_0 = delete_calls;
do_test (char ());
const int new_1 = new_calls - new_0;
const int delete_1 = delete_calls - delete_0;
// verify that test doesn't leak any dynamically allocated storage
rw_assert (0 == new_1 - delete_1, 0, __LINE__,
"test leaked %d blocks of memory", new_1 - delete_1);
rw_assert (0 == init_new_calls, 0, __LINE__,
"iostream initialization called operator new() %d times, "
"0 expected", init_new_calls);
#ifdef _RWSTD_NO_REPLACEABLE_NEW_DELETE
rw_warn (0, 0, __LINE__,
"replacement operators new and delete not tested: "
"_RWSTD_NO_REPLACEABLE_NEW_DELETE #defined");
#endif // _RWSTD_NO_REPLACEABLE_NEW_DELETE
return 0;
}
/**************************************************************************/
#ifndef _RWSTD_NO_REPLACEABLE_NEW_DELETE
# include <new>
# ifndef _RWSTD_BAD_ALLOC
// #define if not #defined by <new> (SunPro #includes its
// own <new> regardless of the preprocessor search path)
# define _RWSTD_BAD_ALLOC _STD::bad_alloc
# endif // _RWSTD_BAD_ALLOC
void* operator new (std::size_t n) _THROWS ((_RWSTD_BAD_ALLOC))
{
static int recursion;
++recursion;
if (rw_opt_no_replacement_new) {
static int noted; // prevent multiple notes
rw_note (noted++, 0, __LINE__,
"test of replacement operator new disabled");
}
else if (1 != recursion) {
// avoid calling rw_warn() except when it has something
// to warn about in case operator new() is being called
// by the compiler's C++ runtime (e.g., HP aCC 6.16)
// when the driver hasn't been initialized yet (otherwise
// the driver aborts)
rw_warn (1 == recursion, 0, __LINE__,
"recursive call to replacement operator new()");
}
else {
// initialize iostreams (verifies that initialization
// succeeds and is complete even if it occurs recursively)
static std::ios_base::Init io_initializer;
// use cout from within new to verify that the static local
// ios_base::Init properly initializes iostream objects
std::cout << "[replacement operator new (" << n << ")]\n";
}
++new_calls;
--recursion;
void* const ptr = std::malloc (n);
if (!ptr)
_THROW (_RWSTD_BAD_ALLOC ());
return ptr;
}
void operator delete (void *ptr) _THROWS (())
{
static int recursion;
++recursion;
if (rw_opt_no_replacement_delete) {
static int noted; // prevent multiple notes
rw_note (noted++, 0, __LINE__,
"test of replacement operator delete disabled");
}
else if (rw_warn (1 == recursion, 0, __LINE__,
"recursive call to replacement operator delete()")) {
std::cout << "[replacement operator delete (" << ptr << ")]\n";
}
--recursion;
if (ptr)
++delete_calls;
std::free (ptr);
}
void* operator new[] (std::size_t n) _THROWS ((_RWSTD_BAD_ALLOC))
{
return operator new (n);
}
void operator delete[] (void *p) _THROWS (())
{
operator delete (p);
}
#endif // _RWSTD_NO_REPLACEABLE_NEW_DELETE
/**************************************************************************/
int main (int argc, char *argv[])
{
init_new_calls = new_calls;
init_delete_calls = delete_calls;
return rw_test (argc, argv, __FILE__,
"lib.iostream.objects",
0, // no comment
run_test,
"|-no-global-dtors# "
"|-no-replacement-new# "
"|-no-replacement-delete#",
&rw_opt_no_global_dtors,
&rw_opt_no_replacement_new,
&rw_opt_no_replacement_delete);
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff