Geant4 Cross Reference |
1 // 1 // 2 // ******************************************* 2 // ******************************************************************** 3 // * License and Disclaimer 3 // * License and Disclaimer * 4 // * 4 // * * 5 // * The Geant4 software is copyright of th 5 // * The Geant4 software is copyright of the Copyright Holders of * 6 // * the Geant4 Collaboration. It is provided 6 // * the Geant4 Collaboration. It is provided under the terms and * 7 // * conditions of the Geant4 Software License 7 // * conditions of the Geant4 Software License, included in the file * 8 // * LICENSE and available at http://cern.ch/ 8 // * LICENSE and available at http://cern.ch/geant4/license . These * 9 // * include a list of copyright holders. 9 // * include a list of copyright holders. * 10 // * 10 // * * 11 // * Neither the authors of this software syst 11 // * Neither the authors of this software system, nor their employing * 12 // * institutes,nor the agencies providing fin 12 // * institutes,nor the agencies providing financial support for this * 13 // * work make any representation or warran 13 // * work make any representation or warranty, express or implied, * 14 // * regarding this software system or assum 14 // * regarding this software system or assume any liability for its * 15 // * use. Please see the license in the file 15 // * use. Please see the license in the file LICENSE and URL above * 16 // * for the full disclaimer and the limitatio 16 // * for the full disclaimer and the limitation of liability. * 17 // * 17 // * * 18 // * This code implementation is the result 18 // * This code implementation is the result of the scientific and * 19 // * technical work of the GEANT4 collaboratio 19 // * technical work of the GEANT4 collaboration. * 20 // * By using, copying, modifying or distri 20 // * By using, copying, modifying or distributing the software (or * 21 // * any work based on the software) you ag 21 // * any work based on the software) you agree to acknowledge its * 22 // * use in resulting scientific publicati 22 // * use in resulting scientific publications, and indicate your * 23 // * acceptance of all terms of the Geant4 Sof 23 // * acceptance of all terms of the Geant4 Software license. * 24 // ******************************************* 24 // ******************************************************************** 25 // 25 // 26 // G4Allocator << 26 // >> 27 // $Id$ >> 28 // >> 29 // >> 30 // ------------------------------------------------------------ >> 31 // GEANT 4 class header file 27 // 32 // 28 // Class Description: 33 // Class Description: 29 // 34 // 30 // A class for fast allocation of objects to t 35 // A class for fast allocation of objects to the heap through a pool of 31 // chunks organised as linked list. It's meant 36 // chunks organised as linked list. It's meant to be used by associating 32 // it to the object to be allocated and defini 37 // it to the object to be allocated and defining for it new and delete 33 // operators via MallocSingle() and FreeSingle 38 // operators via MallocSingle() and FreeSingle() methods. 34 << 39 35 // ---------------- G4Allocator --------- 40 // ---------------- G4Allocator ---------------- 36 // 41 // 37 // Author: G.Cosmo (CERN), November 2000 42 // Author: G.Cosmo (CERN), November 2000 38 // ------------------------------------------- << 43 // ------------------------------------------------------------ 39 #ifndef G4Allocator_hh << 44 40 #define G4Allocator_hh 1 << 45 #ifndef G4Allocator_h >> 46 #define G4Allocator_h 1 41 47 42 #include <cstddef> 48 #include <cstddef> 43 #include <typeinfo> 49 #include <typeinfo> 44 50 45 #include "G4AllocatorPool.hh" 51 #include "G4AllocatorPool.hh" 46 52 47 class G4AllocatorBase 53 class G4AllocatorBase 48 { 54 { 49 public: << 55 public: 50 G4AllocatorBase(); << 56 G4AllocatorBase(); 51 virtual ~G4AllocatorBase() = default; << 57 virtual ~G4AllocatorBase(); 52 virtual void ResetStorage() << 58 virtual void ResetStorage()=0; 53 virtual std::size_t GetAllocatedSize() const << 59 virtual size_t GetAllocatedSize() const=0; 54 virtual int GetNoPages() const << 60 virtual int GetNoPages() const=0; 55 virtual std::size_t GetPageSize() const << 61 virtual size_t GetPageSize() const=0; 56 virtual void IncreasePageSize(unsigned int s << 62 virtual void IncreasePageSize( unsigned int sz )=0; 57 virtual const char* GetPoolType() const << 63 virtual const char* GetPoolType() const=0; 58 }; 64 }; 59 65 60 template <class Type> 66 template <class Type> 61 class G4Allocator : public G4AllocatorBase 67 class G4Allocator : public G4AllocatorBase 62 { 68 { 63 public: << 69 public: // with description 64 G4Allocator() throw(); << 70 65 ~G4Allocator() throw() override; << 71 G4Allocator() throw(); 66 // Constructor & destructor << 72 ~G4Allocator() throw(); 67 << 73 // Constructor & destructor 68 inline Type* MallocSingle(); << 74 69 inline void FreeSingle(Type* anElement); << 75 inline Type* MallocSingle(); 70 // Malloc and Free methods to be used when o << 76 inline void FreeSingle(Type* anElement); 71 // new and delete operators in the client <T << 77 // Malloc and Free methods to be used when overloading 72 << 78 // new and delete operators in the client <Type> object 73 inline void ResetStorage() override; << 79 74 // Returns allocated storage to the free sto << 80 inline void ResetStorage(); 75 // Note: contents in memory are lost using t << 81 // Returns allocated storage to the free store, resets allocator. 76 << 82 // Note: contents in memory are lost using this call ! 77 inline std::size_t GetAllocatedSize() const << 83 78 // Returns the size of the total memory allo << 84 inline size_t GetAllocatedSize() const; 79 inline int GetNoPages() const override; << 85 // Returns the size of the total memory allocated 80 // Returns the total number of allocated pag << 86 inline int GetNoPages() const; 81 inline std::size_t GetPageSize() const overr << 87 // Returns the total number of allocated pages 82 // Returns the current size of a page << 88 inline size_t GetPageSize() const; 83 inline void IncreasePageSize(unsigned int sz << 89 // Returns the current size of a page 84 // Resets allocator and increases default pa << 90 inline void IncreasePageSize( unsigned int sz ); 85 << 91 // Resets allocator and increases default page size of a given factor 86 inline const char* GetPoolType() const overr << 92 87 // Returns the type_info Id of the allocated << 93 inline const char* GetPoolType() const; 88 << 94 // Returns the type_info Id of the allocated type in the pool 89 // This public section includes standard met << 95 90 // required if the allocator is to be used a << 96 public: // without description 91 // allocator for STL containers. << 97 92 // NOTE: the code below is a trivial impleme << 98 // This public section includes standard methods and types 93 // this class an STL compliant allocat << 99 // required if the allocator is to be used as alternative 94 // It is anyhow NOT recommended to use << 100 // allocator for STL containers. 95 // alternative allocator for STL conta << 101 // NOTE: the code below is a trivial implementation to make 96 << 102 // this class an STL compliant allocator. 97 using value_type = Type; << 103 // It is anyhow NOT recommended to use this class as 98 using size_type = std::size_t; << 104 // alternative allocator for STL containers ! 99 using difference_type = ptrdiff_t; << 105 100 using pointer = Type*; << 106 typedef Type value_type; 101 using const_pointer = const Type*; << 107 typedef size_t size_type; 102 using reference = Type&; << 108 typedef ptrdiff_t difference_type; 103 using const_reference = const Type&; << 109 typedef Type* pointer; 104 << 110 typedef const Type* const_pointer; 105 template <class U> << 111 typedef Type& reference; 106 G4Allocator(const G4Allocator<U>& right) thr << 112 typedef const Type& const_reference; 107 : mem(right.mem) << 113 108 {} << 114 template <class U> G4Allocator(const G4Allocator<U>& right) throw() 109 // Copy constructor << 115 : mem(right.mem) {} 110 << 116 // Copy constructor 111 pointer address(reference r) const { return << 117 112 const_pointer address(const_reference r) con << 118 pointer address(reference r) const { return &r; } 113 // Returns the address of values << 119 const_pointer address(const_reference r) const { return &r; } 114 << 120 // Returns the address of values 115 pointer allocate(size_type n, void* = nullpt << 121 116 { << 122 pointer allocate(size_type n, void* = 0) 117 // Allocates space for n elements of type << 123 { 118 // << 124 // Allocates space for n elements of type Type, but does not initialise 119 Type* mem_alloc = 0; << 125 // 120 if(n == 1) << 126 Type* mem_alloc = 0; 121 mem_alloc = MallocSingle(); << 127 if (n == 1) 122 else << 128 mem_alloc = MallocSingle(); 123 mem_alloc = static_cast<Type*>(::operato << 129 else 124 return mem_alloc; << 130 mem_alloc = static_cast<Type*>(::operator new(n*sizeof(Type))); 125 } << 131 return mem_alloc; 126 void deallocate(pointer p, size_type n) << 132 } 127 { << 133 void deallocate(pointer p, size_type n) 128 // Deallocates n elements of type Type, bu << 134 { 129 // << 135 // Deallocates n elements of type Type, but doesn't destroy 130 if(n == 1) << 136 // 131 FreeSingle(p); << 137 if (n == 1) 132 else << 138 FreeSingle(p); 133 ::operator delete((void*) p); << 139 else 134 return; << 140 ::operator delete((void*)p); 135 } << 141 return; 136 << 142 } 137 void construct(pointer p, const Type& val) { << 143 138 // Initialises *p by val << 144 void construct(pointer p, const Type& val) { new((void*)p) Type(val); } 139 void destroy(pointer p) { p->~Type(); } << 145 // Initialises *p by val 140 // Destroy *p but doesn't deallocate << 146 void destroy(pointer p) { p->~Type(); } 141 << 147 // Destroy *p but doesn't deallocate 142 size_type max_size() const throw() << 148 143 { << 149 size_type max_size() const throw() 144 // Returns the maximum number of elements << 150 { 145 // << 151 // Returns the maximum number of elements that can be allocated 146 return 2147483647 / sizeof(Type); << 152 // 147 } << 153 return 2147483647/sizeof(Type); 148 << 154 } 149 template <class U> << 155 150 struct rebind << 156 template <class U> 151 { << 157 struct rebind { typedef G4Allocator<U> other; }; 152 using other = G4Allocator<U>; << 158 // Rebind allocator to type U 153 }; << 159 154 // Rebind allocator to type U << 160 G4AllocatorPool mem; 155 << 161 // Pool of elements of sizeof(Type) 156 G4AllocatorPool mem; << 162 157 // Pool of elements of sizeof(Type) << 163 private: 158 << 164 159 private: << 165 const char* tname; 160 const char* tname; << 166 // Type name identifier 161 // Type name identifier << 162 }; 167 }; 163 168 164 // ------------------------------------------- 169 // ------------------------------------------------------------ 165 // Inline implementation 170 // Inline implementation 166 // ------------------------------------------- 171 // ------------------------------------------------------------ 167 172 168 // Initialization of the static pool 173 // Initialization of the static pool 169 // 174 // 170 // template <class Type> G4AllocatorPool G4All 175 // template <class Type> G4AllocatorPool G4Allocator<Type>::mem(sizeof(Type)); 171 176 172 // ******************************************* 177 // ************************************************************ 173 // G4Allocator constructor 178 // G4Allocator constructor 174 // ******************************************* 179 // ************************************************************ 175 // 180 // 176 template <class Type> 181 template <class Type> 177 G4Allocator<Type>::G4Allocator() throw() 182 G4Allocator<Type>::G4Allocator() throw() 178 : mem(sizeof(Type)) 183 : mem(sizeof(Type)) 179 { 184 { 180 tname = typeid(Type).name(); 185 tname = typeid(Type).name(); 181 } 186 } 182 187 183 // ******************************************* 188 // ************************************************************ 184 // G4Allocator destructor 189 // G4Allocator destructor 185 // ******************************************* 190 // ************************************************************ 186 // 191 // 187 template <class Type> 192 template <class Type> 188 G4Allocator<Type>::~G4Allocator() throw() = de << 193 G4Allocator<Type>::~G4Allocator() throw() >> 194 { >> 195 } 189 196 190 // ******************************************* 197 // ************************************************************ 191 // MallocSingle 198 // MallocSingle 192 // ******************************************* 199 // ************************************************************ 193 // 200 // 194 template <class Type> 201 template <class Type> 195 Type* G4Allocator<Type>::MallocSingle() 202 Type* G4Allocator<Type>::MallocSingle() 196 { 203 { 197 return static_cast<Type*>(mem.Alloc()); 204 return static_cast<Type*>(mem.Alloc()); 198 } 205 } 199 206 200 // ******************************************* 207 // ************************************************************ 201 // FreeSingle 208 // FreeSingle 202 // ******************************************* 209 // ************************************************************ 203 // 210 // 204 template <class Type> 211 template <class Type> 205 void G4Allocator<Type>::FreeSingle(Type* anEle 212 void G4Allocator<Type>::FreeSingle(Type* anElement) 206 { 213 { 207 mem.Free(anElement); 214 mem.Free(anElement); 208 return; 215 return; 209 } 216 } 210 217 211 // ******************************************* 218 // ************************************************************ 212 // ResetStorage 219 // ResetStorage 213 // ******************************************* 220 // ************************************************************ 214 // 221 // 215 template <class Type> 222 template <class Type> 216 void G4Allocator<Type>::ResetStorage() 223 void G4Allocator<Type>::ResetStorage() 217 { 224 { 218 // Clear all allocated storage and return it 225 // Clear all allocated storage and return it to the free store 219 // 226 // 220 mem.Reset(); 227 mem.Reset(); 221 return; 228 return; 222 } 229 } 223 230 224 // ******************************************* 231 // ************************************************************ 225 // GetAllocatedSize 232 // GetAllocatedSize 226 // ******************************************* 233 // ************************************************************ 227 // 234 // 228 template <class Type> 235 template <class Type> 229 std::size_t G4Allocator<Type>::GetAllocatedSiz << 236 size_t G4Allocator<Type>::GetAllocatedSize() const 230 { 237 { 231 return mem.Size(); 238 return mem.Size(); 232 } 239 } 233 240 234 // ******************************************* 241 // ************************************************************ 235 // GetNoPages 242 // GetNoPages 236 // ******************************************* 243 // ************************************************************ 237 // 244 // 238 template <class Type> 245 template <class Type> 239 int G4Allocator<Type>::GetNoPages() const 246 int G4Allocator<Type>::GetNoPages() const 240 { 247 { 241 return mem.GetNoPages(); 248 return mem.GetNoPages(); 242 } 249 } 243 250 244 // ******************************************* 251 // ************************************************************ 245 // GetPageSize 252 // GetPageSize 246 // ******************************************* 253 // ************************************************************ 247 // 254 // 248 template <class Type> 255 template <class Type> 249 size_t G4Allocator<Type>::GetPageSize() const 256 size_t G4Allocator<Type>::GetPageSize() const 250 { 257 { 251 return mem.GetPageSize(); 258 return mem.GetPageSize(); 252 } 259 } 253 260 254 // ******************************************* 261 // ************************************************************ 255 // IncreasePageSize 262 // IncreasePageSize 256 // ******************************************* 263 // ************************************************************ 257 // 264 // 258 template <class Type> 265 template <class Type> 259 void G4Allocator<Type>::IncreasePageSize(unsig << 266 void G4Allocator<Type>::IncreasePageSize( unsigned int sz ) 260 { 267 { 261 ResetStorage(); 268 ResetStorage(); 262 mem.GrowPageSize(sz); << 269 mem.GrowPageSize(sz); 263 } 270 } 264 271 265 // ******************************************* 272 // ************************************************************ 266 // GetPoolType 273 // GetPoolType 267 // ******************************************* 274 // ************************************************************ 268 // 275 // 269 template <class Type> 276 template <class Type> 270 const char* G4Allocator<Type>::GetPoolType() c 277 const char* G4Allocator<Type>::GetPoolType() const 271 { 278 { 272 return tname; 279 return tname; 273 } 280 } 274 281 275 // ******************************************* 282 // ************************************************************ 276 // operator== 283 // operator== 277 // ******************************************* 284 // ************************************************************ 278 // 285 // 279 template <class T1, class T2> 286 template <class T1, class T2> 280 bool operator==(const G4Allocator<T1>&, const << 287 bool operator== (const G4Allocator<T1>&, const G4Allocator<T2>&) throw() 281 { 288 { 282 return true; 289 return true; 283 } 290 } 284 291 285 // ******************************************* 292 // ************************************************************ 286 // operator!= 293 // operator!= 287 // ******************************************* 294 // ************************************************************ 288 // 295 // 289 template <class T1, class T2> 296 template <class T1, class T2> 290 bool operator!=(const G4Allocator<T1>&, const << 297 bool operator!= (const G4Allocator<T1>&, const G4Allocator<T2>&) throw() 291 { 298 { 292 return false; 299 return false; 293 } 300 } 294 301 295 #endif 302 #endif 296 303