403 lines
11 KiB
C++
403 lines
11 KiB
C++
// -*- 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: _allocator.h 614913 2008-01-24 16:22:31Z faridz $
|
|
*
|
|
***************************************************************************
|
|
*
|
|
* 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.
|
|
*
|
|
**************************************************************************/
|
|
|
|
#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);
|
|
|
|
} // 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)
|
|
#else
|
|
void deallocate (void* __p, size_type __n)
|
|
#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);
|
|
}
|
|
|
|
void destroy (pointer __p) {
|
|
_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) {
|
|
_RW::__rw_deallocate (_RWSTD_CONST_CAST (_TypeT*, __p), __nelems);
|
|
}
|
|
#else
|
|
void deallocate (const void* __p, size_type __nbytes) {
|
|
_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);
|
|
}
|
|
|
|
void destroy (const_pointer __p) {
|
|
_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
|