blob: 7a38d45bf32a10fad14a9b0bb4bf435eafa9f584 [file] [log] [blame]
// -*- C++ -*-
/***************************************************************************
*
* _allocator.h - definition of the class template allocator
*
* This is an internal header file used to implement the C++ Standard
* Library. It should never be #included directly by a program.
*
* $Id$
*
***************************************************************************
*
* Copyright (c) 1994
* Hewlett-Packard Company
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation. Hewlett-Packard Company makes no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
*
***************************************************************************
*
* 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, Inc.
*
**************************************************************************/
#ifndef _RWSTD_RW_ALLOCATOR_H_INCLUDED
#define _RWSTD_RW_ALLOCATOR_H_INCLUDED
#ifndef _RWSTD_SPECIALIZED_H_INCLUDED
# include <rw/_specialized.h>
#endif // _RWSTD_SPECIALIZED_H_INCLUDED
_RWSTD_NAMESPACE (__rw) {
// [de]allocate storage (in bytes)
_RWSTD_EXPORT void*
__rw_allocate (_RWSTD_SIZE_T, int = 0);
_RWSTD_EXPORT void
__rw_deallocate (void*, _RWSTD_SIZE_T, int = 0) _THROWS (());
} // namespace __rw
_RWSTD_NAMESPACE (std) {
template <class _TypeT> class
allocator;
_RWSTD_SPECIALIZED_CLASS
class allocator<void>
{
public:
typedef void value_type;
typedef value_type* pointer;
typedef const value_type* const_pointer;
#ifdef _RWSTD_ALLOCATOR
template <class _TypeU>
struct rebind {
typedef allocator<_TypeU> other;
};
#endif // _RWSTD_ALLOCATOR
};
template <class _TypeT>
class allocator
{
public:
typedef _RWSTD_SIZE_T size_type;
typedef _RWSTD_PTRDIFF_T difference_type;
typedef _TypeT value_type;
typedef value_type* pointer;
typedef const value_type* const_pointer;
typedef value_type& reference;
typedef const value_type& const_reference;
allocator () _THROWS (()) { }
allocator (const allocator &__rhs) _THROWS (()) {
// working around an HP aCC warning 431
_RWSTD_UNUSED (__rhs);
}
#ifdef _RWSTD_ALLOCATOR
template <class _TypeU>
struct rebind {
typedef allocator<_TypeU> other;
};
template <class _TypeU>
allocator (const allocator<_TypeU>&) _THROWS (()) { }
template <class _TypeU>
allocator&
operator= (const allocator<_TypeU>&) _THROWS (()) {
return *this;
}
#endif // _RWSTD_ALLOCATOR
pointer address (reference __x) const {
// lwg issue 350
return _RWSTD_REINTERPRET_CAST (pointer,
&_RWSTD_REINTERPRET_CAST (char&, __x));
}
const_pointer address (const_reference __x) const {
// lwg issue 350
return _RWSTD_REINTERPRET_CAST (const_pointer,
&_RWSTD_REINTERPRET_CAST (const char&, __x));
}
pointer allocate (size_type __n, allocator<void>::const_pointer = 0) {
#ifdef _RWSTD_ALLOCATOR
return _RWSTD_STATIC_CAST (pointer,
_RW::__rw_allocate (__n * sizeof (value_type)));
#else
return _RWSTD_STATIC_CAST (pointer, _RW::__rw_allocate (__n));
#endif // _RWSTD_ALLOCATOR
}
#ifdef _RWSTD_ALLOCATOR
void deallocate (pointer __p, size_type __n) _THROWS (())
#else
void deallocate (void* __p, size_type __n) _THROWS (())
#endif // _RWSTD_ALLOCATOR
{
_RW::__rw_deallocate (__p, __n);
}
// 20.4.1.1, p11 - the largest N for which allocate (N) might succeed
size_type max_size () const _THROWS (()) {
return size_type (_RWSTD_SIZE_MAX) / sizeof (value_type)
? size_type (size_type (_RWSTD_SIZE_MAX) / sizeof (value_type))
: size_type (1);
}
void construct (pointer __p, const_reference __val) {
_RW::__rw_construct (__p, __val);
}
// declared as nothrow since the behavior of programs that
// instantiate library templates on types whose dtors throw
// is undefined
void destroy (pointer __p) _RWSTD_ATTRIBUTE_NOTHROW {
_RWSTD_ASSERT (0 != __p);
__p->~_TypeT ();
}
};
#if !defined (_RWSTD_NO_CLASS_PARTIAL_SPEC) \
&& !defined (_RWSTD_NO_EXT_CONST_ALLOCATOR)
// extension: allocates/constructs/destroys const elements
template <class _TypeT>
class allocator<const _TypeT>
{
public:
typedef _RWSTD_SIZE_T size_type;
typedef _RWSTD_PTRDIFF_T difference_type;
typedef const _TypeT value_type;
typedef const value_type* pointer;
typedef const value_type* const_pointer;
typedef const value_type& reference;
typedef const value_type& const_reference;
allocator () _THROWS (()) { }
allocator (const allocator &__rhs) _THROWS (()) {
// working around an HP aCC warning 431
_RWSTD_UNUSED (__rhs);
}
#ifdef _RWSTD_ALLOCATOR
template <class _TypeU>
struct rebind {
typedef allocator<_TypeU> other;
};
template <class _TypeU>
allocator (const allocator<_TypeU>&) _THROWS (()) { }
template <class _TypeU>
allocator& operator= (const allocator<_TypeU>&) _THROWS (()) {
return *this;
}
#endif // _RWSTD_ALLOCATOR
const_pointer address (const_reference __x) const {
// lwg issue 350
return _RWSTD_REINTERPRET_CAST (const_pointer,
&_RWSTD_REINTERPRET_CAST (const char&, __x));
}
// avoid the use of allocator<void>::const_pointer below
// to work around a SunPro 5.3 (and prior) bug
const_pointer allocate (size_type __n, const void* = 0) {
#ifdef _RWSTD_ALLOCATOR
return _RWSTD_STATIC_CAST (const_pointer,
_RWSTD_CONST_CAST (const void*,
_RW::__rw_allocate (__n * sizeof (value_type))));
#else
return _RWSTD_STATIC_CAST (const_pointer,
_RWSTD_CONST_CAST (const void*,
_RW::__rw_allocate (__n)));
#endif // _RWSTD_ALLOCATOR
}
#ifdef _RWSTD_ALLOCATOR
void deallocate (const_pointer __p, size_type __nelems) _THROWS (()) {
_RW::__rw_deallocate (_RWSTD_CONST_CAST (_TypeT*, __p), __nelems);
}
#else
void deallocate (const void* __p, size_type __nbytes) _THROWS (()) {
_RW::__rw_deallocate (_RWSTD_CONST_CAST (void*, __p), __nbytes);
}
#endif // _RWSTD_ALLOCATOR
// 20.4.1.1, p11 - the largest N for which allocate (N) might succeed
size_type max_size () const _THROWS (()) {
return size_type (_RWSTD_SIZE_MAX) / sizeof (value_type)
? size_type (size_type (_RWSTD_SIZE_MAX) / sizeof (value_type))
: size_type (1);
}
void construct (const_pointer __p, const_reference __val) {
_RW::__rw_construct (_RWSTD_CONST_CAST (_TypeT*, __p), __val);
}
// declared as nothrow since the behavior of programs that
// instantiate library templates on types whose dtors throw
// is undefined
void destroy (const_pointer __p) _RWSTD_ATTRIBUTE_NOTHROW {
_RWSTD_ASSERT (0 != __p);
__p->~_TypeT ();
}
};
#endif // !_RWSTD_NO_CLASS_PARTIAL_SPEC && !_RWSTD_NO_EXT_CONST_ALLOCATOR)
// allocator_interface provides all types and typed functions. Memory
// allocated as raw bytes using the class provided by the Allocator
// template parameter. allocator_interface casts appropriately.
//
// Multiple allocator_interface objects can attach to a single
// allocator, thus allowing one allocator to allocate all storage
// for a container, regardless of how many types are involved.
//
// The only real restriction is that pointer and reference are
// hard coded as _TypeT* and _TypeT&. Partial specialization would
// get around this.
//
#ifndef _RWSTD_ALLOCATOR
template <class _Allocator, class _TypeT>
class allocator_interface
{
public:
typedef _Allocator allocator_type;
typedef _TypeT value_type;
typedef value_type* pointer;
typedef const value_type* const_pointer;
typedef value_type& reference;
typedef const value_type& const_reference;
typedef _TYPENAME allocator_type::size_type size_type;
typedef _TYPENAME allocator_type::difference_type difference_type;
protected:
allocator_type _C_alloc;
public:
allocator_interface() _THROWS (()) { }
allocator_interface (const allocator_type &__alloc) _THROWS (())
: _C_alloc (__alloc) { }
operator allocator_type& () {
return _C_alloc;
}
pointer address (reference __x) const {
// lwg issue 350
return _RWSTD_REINTERPRET_CAST (pointer,
&_RWSTD_REINTERPRET_CAST (char&, __x));
}
const_pointer address (const_reference __x) const {
// lwg issue 350
return _RWSTD_REINTERPRET_CAST (const_pointer,
&_RWSTD_REINTERPRET_CAST (const char&, __x));
}
size_type max_size () const {
return _C_alloc.max_size () / sizeof (value_type);
}
pointer allocate (size_type __n, const void* __p = 0) {
return (pointer)_C_alloc.allocate (__n * sizeof (value_type), __p);
}
void deallocate (pointer __p, size_type __n) {
_C_alloc.deallocate (__p, __n);
}
void construct (pointer __p, const_reference __val) {
_RW::__rw_construct(__p, __val);
}
void destroy (pointer __p) const {
_RWSTD_ASSERT (0 != __p);
__p->~_TypeT ();
}
};
_RWSTD_SPECIALIZED_CLASS
class allocator_interface<allocator<void>, void>
{
public:
typedef allocator<void> allocator_type;
typedef void* pointer;
typedef const void* const_pointer;
typedef void value_type;
protected:
allocator_type _C_alloc;
public:
allocator_interface () _THROWS (()) { }
allocator_interface (const allocator<void>& __rhs) _THROWS (())
: _C_alloc (__rhs) { }
};
template <class _TypeT, class _TypeU, class _TypeV, class _TypeW>
inline bool
operator== (const allocator_interface<_TypeT, _TypeU>&,
const allocator_interface<_TypeV, _TypeW>&) _THROWS (())
{
return true;
}
#endif // _RWSTD_ALLOCATOR
template <class _TypeT, class _TypeU>
inline bool
operator== (const allocator<_TypeT>&, const allocator<_TypeU>&) _THROWS (())
{
return true;
}
#ifndef _RWSTD_NO_NAMESPACE
template <class _TypeT, class _TypeU>
inline bool
operator!= (const allocator<_TypeT>& __x,
const allocator<_TypeU>& __y) _THROWS (())
{
return !(__x == __y);
}
#endif // _RWSTD_NO_NAMESPACE
} // namespace std
#endif // _RWSTD_RW_ALLOCATOR_H_INCLUDED