first commit
This commit is contained in:
453
extern/stdcxx/4.2.1/tests/iostream/27.objects.cpp
vendored
Normal file
453
extern/stdcxx/4.2.1/tests/iostream/27.objects.cpp
vendored
Normal 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);
|
||||
}
|
||||
Reference in New Issue
Block a user