blob: 5bcf90133c141fb17325377ddf4b947e59ab81b2 [file] [log] [blame]
/***************************************************************************
*
* memory.cpp - source for the C++ Standard Library
* dynamic memory management functions
*
* $Id$
*
***************************************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed
* with this work for additional information regarding copyright
* ownership. The ASF licenses this file to you under the Apache
* License, Version 2.0 (the License); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
* implied. See the License for the specific language governing
* permissions and limitations under the License.
*
* Copyright 1994-2006 Rogue Wave Software.
*
**************************************************************************/
#define _RWSTD_LIB_SRC
#include <rw/_error.h>
#include <rw/_mutex.h>
#include <new>
#include <stdlib.h>
#include <rw/_defs.h>
_RWSTD_NAMESPACE (__rw) {
_RWSTD_EXPORT void*
__rw_allocate (_RWSTD_SIZE_T nbytes, int /* = 0 */)
{
void *ptr = 0;
_TRY {
#ifndef _RWSTD_NO_NEW_OFLOW_SAFE
ptr = ::operator new (nbytes);
#else // if defined (_RWSTD_NO_NEW_OFLOW_SAFE)
// operator new() doesn't check for argument overflow,
// check before calling it and fail if `n' looks too big
if (nbytes < (_RWSTD_SIZE_T)-1 - 256)
ptr = ::operator new (nbytes);
#endif // _RWSTD_NO_NEW_OFLOW_SAFE
}
_CATCH (...) {
// prevent bad_alloc raised by the compiler
}
// fix broken ::operator new ()
if (0 == ptr)
_RW::__rw_throw (_RWSTD_ERROR_FIRST + 3 /* == bad_alloc */);
return ptr;
}
_RWSTD_EXPORT void
__rw_deallocate (void *p, _RWSTD_SIZE_T, int /* = 0 */)
{
::operator delete (p);
}
} // namespace __rw
#if defined _RWSTD_NEW_INCLUDED
// define operator new and delete and bad_alloc members only if our own
// implementation's <new> header (as opposed to the compiler's native C++
// Standard library) has been included; SunPro always #includes its own,
// regardless of compiler options
// The following operators are replaceable; provide definitions if they're
// missing in the compiler support library, and _RWSTD_NO_EXT_OPERATOR_NEW
// is not defined (i.e., not in strict ansi mode). This means that they will
// no longer be replaceable, but at least they will be callable without the
// user providing the definitions
//
#ifndef _RWSTD_NO_EXT_OPERATOR_NEW
# ifdef _RWSTD_NO_OPERATOR_NEW_NOTHROW
_RWSTD_EXPORT void*
operator new (_RWSTD_SIZE_T __size, const _STD::nothrow_t&) _NEW_THROWS (())
{
return malloc (__size);
}
# endif // _RWSTD_NO_OPERATOR_NEW_NOTHROW
# if defined (_RWSTD_NO_OPERATOR_DELETE_NOTHROW) \
&& !defined (_RWSTD_NO_PLACEMENT_DELETE)
_RWSTD_EXPORT void
operator delete (void* __ptr, const _STD::nothrow_t&) _NEW_THROWS (())
{
free (__ptr);
}
# endif // _RWSTD_NO_OPERATOR_DELETE_NOTHROW && _RWSTD_NO_PLACEMENT_DELETE
# ifdef _RWSTD_NO_OPERATOR_NEW_ARRAY
_RWSTD_EXPORT void*
operator new[] (_RWSTD_SIZE_T __size) _NEW_THROWS ((_RWSTD_BAD_ALLOC))
{
return ::operator new (__size);
}
# endif // _RWSTD_NO_OPERATOR_NEW_ARRAY
# ifdef _RWSTD_NO_OPERATOR_NEW_ARRAY_NOTHROW
_RWSTD_EXPORT void*
operator new[] (_RWSTD_SIZE_T __size, const _STD::nothrow_t&) _NEW_THROWS (())
{
_TRY {
return ::operator new (__size);
}
_CATCH (...) {
void *__nil = 0; // prevent a g++ 2.95.2 warning
return __nil; // about operator new returning 0
}
}
# endif // _RWSTD_NO_OPERATOR_NEW_ARRAY_NOTHROW
# ifdef _RWSTD_NO_OPERATOR_DELETE_ARRAY
_RWSTD_EXPORT void
operator delete[] (void* __ptr) _NEW_THROWS (())
{
::operator delete (__ptr);
}
# endif // _RWSTD_NO_OPERATOR_DELETE_ARRAY
# if defined (_RWSTD_NO_OPERATOR_DELETE_ARRAY_NOTHROW) \
&& !defined (_RWSTD_NO_PLACEMENT_DELETE)
_RWSTD_EXPORT void
operator delete[] (void* __ptr, const _STD::nothrow_t&) _NEW_THROWS (())
{
::operator delete[] (__ptr); // ::operator delete[] doesn't throw
}
# endif // _RWSTD_NO_OPERATOR_DELETE_NOTHROW && _RWSTD_NO_PLACEMENT_DELETE
#endif // _RWSTD_NO_EXT_OPERATOR_NEW
//**************************************************************************
#ifdef _MSC_VER
typedef int (*__rw_new_handler_t)(_RWSTD_SIZE_T);
_RWSTD_DLLIMPORT __rw_new_handler_t _set_new_handler (__rw_new_handler_t);
_RWSTD_NAMESPACE (__rw) {
static _STD::new_handler __rw_new_handler /* = 0 */;
static int __rw_new_handler_imp (_RWSTD_SIZE_T)
{
_RWSTD_ASSERT (0 != __rw_new_handler);
__rw_new_handler ();
return 1;
}
} // namespace __rw
_RWSTD_NAMESPACE (std) {
// 18.4.2.3
_RWSTD_EXPORT new_handler
set_new_handler (new_handler handler) _THROWS (())
{
// MSVC's set_new_handler(h) calls assert(h == 0)
// use the _set_new_handler() interface instead
_RWSTD_MT_STATIC_GUARD (new_handler);
new_handler save = _RW::__rw_new_handler;
_RW::__rw_new_handler = handler;
_set_new_handler (_RW::__rw_new_handler_imp);
return save;
}
} // namespace std
#endif // _MSC_VER
//**************************************************************************
_RWSTD_NAMESPACE (std) {
// define std::nothrow only if the symbol doesn't appear
// in the compiler support library to prevent linker errors
// (with gcc -fno-honor-std, don't define if global version exists)
// +----------+-------------------+--------------------+----------------+
// | define? | _NO_STD_NOTHROW_T | _NO_GLOBAL_NOTHROW | _NO_HONOR_STD |
// +----------+-------------------+--------------------+----------------+
// | yes | defined | defined | defined |
// +----------+-------------------+--------------------+----------------+
// | yes | defined | defined | !defined |
// +----------+-------------------+--------------------+----------------+
// | no | defined | !defined | defined |
// +----------+-------------------+--------------------+----------------+
// | no | defined | !defined | !defined |
// +----------+-------------------+--------------------+----------------+
// | no | !defined | defined | defined |
// +----------+-------------------+--------------------+----------------+
// | no | !defined | defined | !defined |
// +----------+-------------------+--------------------+----------------+
// | no | !defined | !defined | defined |
// +----------+-------------------+--------------------+----------------+
// | no | !defined | !defined | !defined |
// +----------+-------------------+--------------------+----------------+
#if defined (_RWSTD_NO_STD_NOTHROW) \
&& ( defined (_RWSTD_NO_GLOBAL_NOTHROW) \
|| !defined (_RWSTD_NO_HONOR_STD))
# if __HP_aCC != 33000 && __HP_aCC != 33100
// HP aCC 3.30 fails to emit data symbols for extern consts
_RWSTD_EXPORT extern const nothrow_t nothrow = nothrow_t ();
# endif // __HP_aCC
#endif // _RWSTD_NO_STD_NOTHROW && _RWSTD_NO_GLOBAL_NOTHROW || ...
} // namespace std
//**************************************************************************
// class bad_alloc members
# if !defined (_RWSTD_NO_STD_BAD_ALLOC) \
|| !defined (_RWSTD_NO_RUNTIME_IN_STD)
_RWSTD_NAMESPACE (std) {
# endif // !_RWSTD_NO_STD_BAD_ALLOC || !_RWSTD_NO_RUNTIME_IN_STD ...
# ifdef _RWSTD_NO_BAD_ALLOC_DEFAULT_CTOR
bad_alloc::
bad_alloc () _THROWS (())
: exception ()
{
// empty
}
# endif // _RWSTD_NO_BAD_ALLOC_DEFAULT_CTOR
# ifdef _RWSTD_NO_BAD_ALLOC_COPY_CTOR
bad_alloc::
bad_alloc (const bad_alloc &rhs) _THROWS (())
: exception (rhs)
{
// empty
}
# endif // _RWSTD_NO_BAD_ALLOC_COPY_CTOR
# ifdef _RWSTD_NO_BAD_ALLOC_DTOR
# if !__INTEL_COMPILER || __INTEL_COMPILER > 800
/* virtual */ bad_alloc::
~bad_alloc () _THROWS (())
{
// empty
}
# endif // Intel C++ > 8.0
# endif // _RWSTD_NO_BAD_ALLOC_DTOR
# ifdef _RWSTD_NO_BAD_ALLOC_ASSIGNMENT
bad_alloc& bad_alloc::
operator= (const bad_alloc &rhs) _THROWS (())
{
exception::operator= (rhs);
return *this;
}
# endif // _RWSTD_NO_BAD_ALLOC_ASSIGNMENT
# ifdef _RWSTD_NO_BAD_ALLOC_WHAT
# if !__INTEL_COMPILER || __INTEL_COMPILER > 800
/* virtual */ const char* bad_alloc::
what () const _THROWS (())
{
return _RWSTD_ERROR_BAD_ALLOC;
}
# endif // Intel C++ > 8.0
# endif // _RWSTD_NO_BAD_ALLOC_WHAT
# if !defined (_RWSTD_NO_STD_BAD_ALLOC) \
|| !defined (_RWSTD_NO_RUNTIME_IN_STD)
} // namespace std
# endif // !_RWSTD_NO_STD_BAD_ALLOC || !_RWSTD_NO_RUNTIME_IN_STD ...
#endif // _RWSTD_NEW_INCLUDED