| // -*- 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 |