00001 // 00002 // ******************************************************************** 00003 // * License and Disclaimer * 00004 // * * 00005 // * The Geant4 software is copyright of the Copyright Holders of * 00006 // * the Geant4 Collaboration. It is provided under the terms and * 00007 // * conditions of the Geant4 Software License, included in the file * 00008 // * LICENSE and available at http://cern.ch/geant4/license . These * 00009 // * include a list of copyright holders. * 00010 // * * 00011 // * Neither the authors of this software system, nor their employing * 00012 // * institutes,nor the agencies providing financial support for this * 00013 // * work make any representation or warranty, express or implied, * 00014 // * regarding this software system or assume any liability for its * 00015 // * use. Please see the license in the file LICENSE and URL above * 00016 // * for the full disclaimer and the limitation of liability. * 00017 // * * 00018 // * This code implementation is the result of the scientific and * 00019 // * technical work of the GEANT4 collaboration. * 00020 // * By using, copying, modifying or distributing the software (or * 00021 // * any work based on the software) you agree to acknowledge its * 00022 // * use in resulting scientific publications, and indicate your * 00023 // * acceptance of all terms of the Geant4 Software license. * 00024 // ******************************************************************** 00025 // 00026 // 00027 // $Id$ 00028 // 00029 // 00030 // ------------------------------------------------------------ 00031 // GEANT 4 class header file 00032 // 00033 // Class Description: 00034 // 00035 // A class for fast allocation of objects to the heap through a pool of 00036 // chunks organised as linked list. It's meant to be used by associating 00037 // it to the object to be allocated and defining for it new and delete 00038 // operators via MallocSingle() and FreeSingle() methods. 00039 00040 // ---------------- G4Allocator ---------------- 00041 // 00042 // Author: G.Cosmo (CERN), November 2000 00043 // ------------------------------------------------------------ 00044 00045 #ifndef G4Allocator_h 00046 #define G4Allocator_h 1 00047 00048 #include <cstddef> 00049 00050 #include "G4AllocatorPool.hh" 00051 00052 template <class Type> 00053 class G4Allocator 00054 { 00055 public: // with description 00056 00057 G4Allocator() throw(); 00058 ~G4Allocator() throw(); 00059 // Constructor & destructor 00060 00061 inline Type* MallocSingle(); 00062 inline void FreeSingle(Type* anElement); 00063 // Malloc and Free methods to be used when overloading 00064 // new and delete operators in the client <Type> object 00065 00066 inline void ResetStorage(); 00067 // Returns allocated storage to the free store, resets allocator. 00068 // Note: contents in memory are lost using this call ! 00069 00070 inline size_t GetAllocatedSize() const; 00071 // Returns the size of the total memory allocated 00072 inline int GetNoPages() const; 00073 // Returns the total number of allocated pages 00074 inline size_t GetPageSize() const; 00075 // Returns the current size of a page 00076 inline void IncreasePageSize( unsigned int sz ); 00077 // Resets allocator and increases default page size of a given factor 00078 00079 public: // without description 00080 00081 // This public section includes standard methods and types 00082 // required if the allocator is to be used as alternative 00083 // allocator for STL containers. 00084 // NOTE: the code below is a trivial implementation to make 00085 // this class an STL compliant allocator. 00086 // It is anyhow NOT recommended to use this class as 00087 // alternative allocator for STL containers ! 00088 00089 typedef Type value_type; 00090 typedef size_t size_type; 00091 typedef ptrdiff_t difference_type; 00092 typedef Type* pointer; 00093 typedef const Type* const_pointer; 00094 typedef Type& reference; 00095 typedef const Type& const_reference; 00096 00097 template <class U> G4Allocator(const G4Allocator<U>& right) throw() 00098 : mem(right.mem) {} 00099 // Copy constructor 00100 00101 pointer address(reference r) const { return &r; } 00102 const_pointer address(const_reference r) const { return &r; } 00103 // Returns the address of values 00104 00105 pointer allocate(size_type n, void* = 0) 00106 { 00107 // Allocates space for n elements of type Type, but does not initialise 00108 // 00109 Type* mem_alloc = 0; 00110 if (n == 1) 00111 mem_alloc = MallocSingle(); 00112 else 00113 mem_alloc = static_cast<Type*>(::operator new(n*sizeof(Type))); 00114 return mem_alloc; 00115 } 00116 void deallocate(pointer p, size_type n) 00117 { 00118 // Deallocates n elements of type Type, but doesn't destroy 00119 // 00120 if (n == 1) 00121 FreeSingle(p); 00122 else 00123 ::operator delete((void*)p); 00124 return; 00125 } 00126 00127 void construct(pointer p, const Type& val) { new((void*)p) Type(val); } 00128 // Initialises *p by val 00129 void destroy(pointer p) { p->~Type(); } 00130 // Destroy *p but doesn't deallocate 00131 00132 size_type max_size() const throw() 00133 { 00134 // Returns the maximum number of elements that can be allocated 00135 // 00136 return 2147483647/sizeof(Type); 00137 } 00138 00139 template <class U> 00140 struct rebind { typedef G4Allocator<U> other; }; 00141 // Rebind allocator to type U 00142 00143 G4AllocatorPool mem; 00144 // Pool of elements of sizeof(Type) 00145 }; 00146 00147 // ------------------------------------------------------------ 00148 // Inline implementation 00149 // ------------------------------------------------------------ 00150 00151 // Initialization of the static pool 00152 // 00153 // template <class Type> G4AllocatorPool G4Allocator<Type>::mem(sizeof(Type)); 00154 00155 // ************************************************************ 00156 // G4Allocator constructor 00157 // ************************************************************ 00158 // 00159 template <class Type> 00160 G4Allocator<Type>::G4Allocator() throw() 00161 : mem(sizeof(Type)) 00162 { 00163 } 00164 00165 // ************************************************************ 00166 // G4Allocator destructor 00167 // ************************************************************ 00168 // 00169 template <class Type> 00170 G4Allocator<Type>::~G4Allocator() throw() 00171 { 00172 } 00173 00174 // ************************************************************ 00175 // MallocSingle 00176 // ************************************************************ 00177 // 00178 template <class Type> 00179 Type* G4Allocator<Type>::MallocSingle() 00180 { 00181 return static_cast<Type*>(mem.Alloc()); 00182 } 00183 00184 // ************************************************************ 00185 // FreeSingle 00186 // ************************************************************ 00187 // 00188 template <class Type> 00189 void G4Allocator<Type>::FreeSingle(Type* anElement) 00190 { 00191 mem.Free(anElement); 00192 return; 00193 } 00194 00195 // ************************************************************ 00196 // ResetStorage 00197 // ************************************************************ 00198 // 00199 template <class Type> 00200 void G4Allocator<Type>::ResetStorage() 00201 { 00202 // Clear all allocated storage and return it to the free store 00203 // 00204 mem.Reset(); 00205 return; 00206 } 00207 00208 // ************************************************************ 00209 // GetAllocatedSize 00210 // ************************************************************ 00211 // 00212 template <class Type> 00213 size_t G4Allocator<Type>::GetAllocatedSize() const 00214 { 00215 return mem.Size(); 00216 } 00217 00218 // ************************************************************ 00219 // GetNoPages 00220 // ************************************************************ 00221 // 00222 template <class Type> 00223 int G4Allocator<Type>::GetNoPages() const 00224 { 00225 return mem.GetNoPages(); 00226 } 00227 00228 // ************************************************************ 00229 // GetPageSize 00230 // ************************************************************ 00231 // 00232 template <class Type> 00233 size_t G4Allocator<Type>::GetPageSize() const 00234 { 00235 return mem.GetPageSize(); 00236 } 00237 00238 // ************************************************************ 00239 // IncreasePageSize 00240 // ************************************************************ 00241 // 00242 template <class Type> 00243 void G4Allocator<Type>::IncreasePageSize( unsigned int sz ) 00244 { 00245 ResetStorage(); 00246 mem.GrowPageSize(sz); 00247 } 00248 00249 // ************************************************************ 00250 // operator== 00251 // ************************************************************ 00252 // 00253 template <class T1, class T2> 00254 bool operator== (const G4Allocator<T1>&, const G4Allocator<T2>&) throw() 00255 { 00256 return true; 00257 } 00258 00259 // ************************************************************ 00260 // operator!= 00261 // ************************************************************ 00262 // 00263 template <class T1, class T2> 00264 bool operator!= (const G4Allocator<T1>&, const G4Allocator<T2>&) throw() 00265 { 00266 return false; 00267 } 00268 00269 #endif