00001 /* 00002 * Copyright 1999-2004 The Apache Software Foundation. 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 00017 #if !defined(ARENAALLOCATOR_INCLUDE_GUARD_1357924680) 00018 #define ARENAALLOCATOR_INCLUDE_GUARD_1357924680 00019 00020 00021 00022 #include <algorithm> 00023 #include <vector> 00024 00025 00026 00027 #include "ArenaBlock.hpp" 00028 00029 00030 00031 XALAN_CPP_NAMESPACE_BEGIN 00032 00033 00034 00035 template<class Type> 00036 class ArenaDeleteFunctor 00037 { 00038 public: 00039 00040 void 00041 operator()(const Type* theType) const 00042 { 00043 #if defined(XALAN_CANNOT_DELETE_CONST) 00044 delete (Type*)theType; 00045 #else 00046 delete theType; 00047 #endif 00048 } 00049 }; 00050 00051 00052 00053 template<class ObjectType, 00054 #if defined(XALAN_NO_DEFAULT_TEMPLATE_ARGUMENTS) 00055 class ArenaBlockType> 00056 #else 00057 class ArenaBlockType = ArenaBlock<ObjectType> > 00058 #endif 00059 class ArenaAllocator 00060 { 00061 public: 00062 00063 typedef typename ArenaBlockType::size_type size_type; 00064 00065 /* 00066 * Construct an instance that will allocate blocks of the specified size. 00067 * 00068 * @param theBlockSize The block size. 00069 */ 00070 ArenaAllocator(size_type theBlockSize) : 00071 m_blockSize(theBlockSize), 00072 m_blocks() 00073 { 00074 } 00075 00076 virtual 00077 ~ArenaAllocator() 00078 { 00079 reset(); 00080 } 00081 00082 /* 00083 * Get size of an ArenaBlock, that is, the number 00084 * of objects in each block. 00085 * 00086 * @return The size of the block 00087 */ 00088 size_type 00089 getBlockSize() const 00090 { 00091 return m_blockSize; 00092 } 00093 00094 /* 00095 * Set size of an ArenaBlock, that is, the number 00096 * of objects in each block. Only affects blocks 00097 * allocated after the call. 00098 * 00099 * @param theSize The size of the block 00100 */ 00101 void 00102 setBlockSize(size_type theSize) 00103 { 00104 m_blockSize = theSize; 00105 } 00106 00107 /* 00108 * Get the number of ArenaBlocks currently allocated. 00109 * 00110 * @return The number of blocks. 00111 */ 00112 size_type 00113 getBlockCount() const 00114 { 00115 return m_blocks.size(); 00116 } 00117 00118 /* 00119 * Allocate a block of the appropriate size for an 00120 * object. Call commitAllocation() when after 00121 * the object is successfully constructed. 00122 * 00123 * @return A pointer to a block of memory 00124 */ 00125 virtual ObjectType* 00126 allocateBlock() 00127 { 00128 if (m_blocks.empty() == true || 00129 m_blocks.back()->blockAvailable() == false) 00130 { 00131 m_blocks.push_back(new ArenaBlockType(m_blockSize)); 00132 } 00133 assert(m_blocks.empty() == false && m_blocks.back() != 0 && m_blocks.back()->blockAvailable() == true); 00134 00135 return m_blocks.back()->allocateBlock(); 00136 } 00137 00138 /* 00139 * Commits the allocation of the previous 00140 * allocateBlock() call. 00141 * 00142 * @param theObject A pointer to a block of memory 00143 */ 00144 virtual void 00145 commitAllocation(ObjectType* theObject) 00146 { 00147 assert(m_blocks.empty() == false && m_blocks.back()->ownsBlock(theObject) == true); 00148 00149 m_blocks.back()->commitAllocation(theObject); 00150 assert(m_blocks.back()->ownsObject(theObject) == true); 00151 } 00152 00153 virtual bool 00154 ownsObject(const ObjectType* theObject) const 00155 { 00156 bool fResult = false; 00157 00158 // Search back for a block that may have allocated the object... 00159 // Note that this-> is required by template lookup rules. 00160 const typename ArenaBlockListType::const_reverse_iterator theEnd = this->m_blocks.rend(); 00161 00162 typename ArenaBlockListType::const_reverse_iterator i = this->m_blocks.rbegin(); 00163 00164 while(i != theEnd) 00165 { 00166 assert(*i != 0); 00167 00168 if ((*i)->ownsObject(theObject) == true) 00169 { 00170 fResult = true; 00171 00172 break; 00173 } 00174 else 00175 { 00176 ++i; 00177 } 00178 } 00179 00180 return fResult; 00181 } 00182 00183 virtual void 00184 reset() 00185 { 00186 00187 XALAN_STD_QUALIFIER for_each( 00188 m_blocks.begin(), 00189 m_blocks.end(), 00190 ArenaDeleteFunctor<ArenaBlockType>()); 00191 00192 m_blocks.clear(); 00193 } 00194 00195 protected: 00196 00197 // data members... 00198 #if defined(XALAN_NO_STD_NAMESPACE) 00199 typedef vector<ArenaBlockType*> ArenaBlockListType; 00200 #else 00201 typedef std::vector<ArenaBlockType*> ArenaBlockListType; 00202 #endif 00203 00204 size_type m_blockSize; 00205 00206 ArenaBlockListType m_blocks; 00207 00208 private: 00209 00210 // Not defined... 00211 ArenaAllocator(const ArenaAllocator<ObjectType, ArenaBlockType>&); 00212 00213 ArenaAllocator<ObjectType, ArenaBlockType>& 00214 operator=(const ArenaAllocator<ObjectType, ArenaBlockType>&); 00215 }; 00216 00217 00218 00219 XALAN_CPP_NAMESPACE_END 00220 00221 00222 00223 #endif // !defined(ARENAALLOCATOR_INCLUDE_GUARD_1357924680)
Doxygen and GraphViz are used to generate this API documentation from the Xalan-C header files.
![]() |
Xalan-C++ XSLT Processor Version 1.8 |
|