1186904Ssam// array allocator -*- C++ -*- 2186904Ssam 3186904Ssam// Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc. 4186904Ssam// 5186904Ssam// This file is part of the GNU ISO C++ Library. This library is free 6186904Ssam// software; you can redistribute it and/or modify it under the 7186904Ssam// terms of the GNU General Public License as published by the 8186904Ssam// Free Software Foundation; either version 2, or (at your option) 9186904Ssam// any later version. 10186904Ssam 11186904Ssam// This library is distributed in the hope that it will be useful, 12186904Ssam// but WITHOUT ANY WARRANTY; without even the implied warranty of 13186904Ssam// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14186904Ssam// GNU General Public License for more details. 15186904Ssam 16186904Ssam// You should have received a copy of the GNU General Public License along 17186904Ssam// with this library; see the file COPYING. If not, write to the Free 18186904Ssam// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 19186904Ssam// USA. 20186904Ssam 21186904Ssam// As a special exception, you may use this file as part of a free software 22186904Ssam// library without restriction. Specifically, if other files instantiate 23186904Ssam// templates or use macros or inline functions from this file, or you compile 24186904Ssam// this file and link it with other files to produce an executable, this 25186904Ssam// file does not by itself cause the resulting executable to be covered by 26186904Ssam// the GNU General Public License. This exception does not however 27186904Ssam// invalidate any other reasons why the executable file might be covered by 28186904Ssam// the GNU General Public License. 29186904Ssam 30186904Ssam/** @file ext/array_allocator.h 31186904Ssam * This file is a GNU extension to the Standard C++ Library. 32186904Ssam */ 33186904Ssam 34186904Ssam#ifndef _ARRAY_ALLOCATOR_H 35186904Ssam#define _ARRAY_ALLOCATOR_H 1 36186904Ssam 37186904Ssam#include <cstddef> 38186904Ssam#include <new> 39186904Ssam#include <bits/functexcept.h> 40186904Ssam#include <tr1/array> 41186904Ssam 42186904Ssam_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) 43186904Ssam 44186904Ssam using std::size_t; 45186904Ssam using std::ptrdiff_t; 46186904Ssam 47186904Ssam /// @brief Base class. 48186904Ssam template<typename _Tp> 49186904Ssam class array_allocator_base 50186904Ssam { 51186904Ssam public: 52186904Ssam typedef size_t size_type; 53186904Ssam typedef ptrdiff_t difference_type; 54186904Ssam typedef _Tp* pointer; 55186904Ssam typedef const _Tp* const_pointer; 56186904Ssam typedef _Tp& reference; 57186904Ssam typedef const _Tp& const_reference; 58186904Ssam typedef _Tp value_type; 59186904Ssam 60186904Ssam pointer 61186904Ssam address(reference __x) const { return &__x; } 62186904Ssam 63186904Ssam const_pointer 64186904Ssam address(const_reference __x) const { return &__x; } 65186904Ssam 66186904Ssam void 67186904Ssam deallocate(pointer, size_type) 68186904Ssam { 69186904Ssam // Does nothing. 70186904Ssam } 71186904Ssam 72186904Ssam size_type 73186904Ssam max_size() const throw() 74186904Ssam { return size_t(-1) / sizeof(_Tp); } 75186904Ssam 76186904Ssam // _GLIBCXX_RESOLVE_LIB_DEFECTS 77186904Ssam // 402. wrong new expression in [some_] allocator::construct 78186904Ssam void 79186904Ssam construct(pointer __p, const _Tp& __val) 80186904Ssam { ::new(__p) value_type(__val); } 81186904Ssam 82186904Ssam void 83186904Ssam destroy(pointer __p) { __p->~_Tp(); } 84186904Ssam }; 85186904Ssam 86186904Ssam /** 87186904Ssam * @brief An allocator that uses previously allocated memory. 88186904Ssam * This memory can be externally, globally, or otherwise allocated. 89186904Ssam */ 90186904Ssam template<typename _Tp, typename _Array = std::tr1::array<_Tp, 1> > 91186904Ssam class array_allocator : public array_allocator_base<_Tp> 92186904Ssam { 93186904Ssam public: 94186904Ssam typedef size_t size_type; 95186904Ssam typedef ptrdiff_t difference_type; 96186904Ssam typedef _Tp* pointer; 97186904Ssam typedef const _Tp* const_pointer; 98186904Ssam typedef _Tp& reference; 99186904Ssam typedef const _Tp& const_reference; 100186904Ssam typedef _Tp value_type; 101186904Ssam typedef _Array array_type; 102186904Ssam 103186904Ssam private: 104186904Ssam array_type* _M_array; 105186904Ssam size_type _M_used; 106186904Ssam 107186904Ssam public: 108186904Ssam template<typename _Tp1, typename _Array1 = _Array> 109186904Ssam struct rebind 110186904Ssam { typedef array_allocator<_Tp1, _Array1> other; }; 111186904Ssam 112186904Ssam array_allocator(array_type* __array = NULL) throw() 113186904Ssam : _M_array(__array), _M_used(size_type()) { } 114186904Ssam 115186904Ssam array_allocator(const array_allocator& __o) throw() 116186904Ssam : _M_array(__o._M_array), _M_used(__o._M_used) { } 117186904Ssam 118186904Ssam template<typename _Tp1, typename _Array1> 119186904Ssam array_allocator(const array_allocator<_Tp1, _Array1>&) throw() 120186904Ssam : _M_array(NULL), _M_used(size_type()) { } 121186904Ssam 122186904Ssam ~array_allocator() throw() { } 123186904Ssam 124186904Ssam pointer 125186904Ssam allocate(size_type __n, const void* = 0) 126186904Ssam { 127186904Ssam if (_M_array == 0 || _M_used + __n > _M_array->size()) 128186904Ssam std::__throw_bad_alloc(); 129186904Ssam pointer __ret = _M_array->begin() + _M_used; 130186904Ssam _M_used += __n; 131186904Ssam return __ret; 132186904Ssam } 133186904Ssam }; 134186904Ssam 135186904Ssam template<typename _Tp, typename _Array> 136186904Ssam inline bool 137186904Ssam operator==(const array_allocator<_Tp, _Array>&, 138186904Ssam const array_allocator<_Tp, _Array>&) 139186904Ssam { return true; } 140186904Ssam 141186904Ssam template<typename _Tp, typename _Array> 142186904Ssam inline bool 143186904Ssam operator!=(const array_allocator<_Tp, _Array>&, 144186904Ssam const array_allocator<_Tp, _Array>&) 145186904Ssam { return false; } 146186904Ssam 147186904Ssam_GLIBCXX_END_NAMESPACE 148186904Ssam 149186904Ssam#endif 150186904Ssam