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 // G4Cache 26 // G4Cache 27 // 27 // 28 // Class Description: 28 // Class Description: 29 // 29 // 30 // Helper classes for Geant4 Multi-Thread 30 // Helper classes for Geant4 Multi-Threaded. 31 // The classes defined in this header fil 31 // The classes defined in this header file provide a thread-private 32 // cache to store a thread-local variable 32 // cache to store a thread-local variable V in a class instance 33 // shared among threads. 33 // shared among threads. 34 // These are templated classes on the to- 34 // These are templated classes on the to-be-stored object. 35 // 35 // 36 // Example: 36 // Example: 37 // Let's assume an instance myObject of c 37 // Let's assume an instance myObject of class G4Shared is sharead between 38 // threads. Still a data member of this c 38 // threads. Still a data member of this class needs to be thread-private. 39 // A typical example of this being a "cac 39 // A typical example of this being a "cache" for a local calculation. 40 // The helper defined here can be used to 40 // The helper defined here can be used to guarantee thread-safe operations 41 // on the thread-private object. 41 // on the thread-private object. 42 // Example: 42 // Example: 43 // class G4Shared 43 // class G4Shared 44 // { 44 // { 45 // G4double sharedData; 45 // G4double sharedData; 46 // G4Cache<G4double> threadPrivate; 46 // G4Cache<G4double> threadPrivate; 47 // void foo() 47 // void foo() 48 // { 48 // { 49 // G4double priv = threadPrivate.G 49 // G4double priv = threadPrivate.Get(); 50 // if ( priv < 10 ) priv += shared 50 // if ( priv < 10 ) priv += sharedData; 51 // threadPrivate.Put( priv ); 51 // threadPrivate.Put( priv ); 52 // } 52 // } 53 // } 53 // } 54 // 54 // 55 // Two variants of the base G4Cache exist 55 // Two variants of the base G4Cache exist. The first one being 56 // G4VectorCache similar to std::vector. 56 // G4VectorCache similar to std::vector. 57 // Example: 57 // Example: 58 // G4VectorCache<G4double> aVect; 58 // G4VectorCache<G4double> aVect; 59 // aVect.Push_back( 3.2 ); 59 // aVect.Push_back( 3.2 ); 60 // aVect.Push_back( 4.1 ); 60 // aVect.Push_back( 4.1 ); 61 // std::cout << aVect[0] << std::endl; 61 // std::cout << aVect[0] << std::endl; 62 // The second one being: 62 // The second one being: 63 // G4MapCache, similar to std::map. 63 // G4MapCache, similar to std::map. 64 // Example: 64 // Example: 65 // G4MapCache<G4int, G4double> aMap; 65 // G4MapCache<G4int, G4double> aMap; 66 // aMap[320]=1.234; 66 // aMap[320]=1.234; 67 // 67 // 68 // See classes definition for details. 68 // See classes definition for details. 69 69 70 // Author: A.Dotti, 21 October 2013 - First im 70 // Author: A.Dotti, 21 October 2013 - First implementation 71 // ------------------------------------------- 71 // -------------------------------------------------------------------- 72 #ifndef G4CACHE_HH 72 #ifndef G4CACHE_HH 73 #define G4CACHE_HH 73 #define G4CACHE_HH 74 74 75 // Debug this code 75 // Debug this code 76 // #define g4cdebug 1 76 // #define g4cdebug 1 77 77 78 #include <atomic> 78 #include <atomic> 79 #include <map> 79 #include <map> 80 #include <system_error> 80 #include <system_error> 81 81 82 #include "G4AutoLock.hh" 82 #include "G4AutoLock.hh" 83 #include "G4CacheDetails.hh" // Thread Local 83 #include "G4CacheDetails.hh" // Thread Local storage details are here 84 84 85 // A templated cache to store a thread-private 85 // A templated cache to store a thread-private data of type VALTYPE. 86 // 86 // 87 template <class VALTYPE> 87 template <class VALTYPE> 88 class G4Cache 88 class G4Cache 89 { 89 { 90 public: 90 public: 91 using value_type = VALTYPE; 91 using value_type = VALTYPE; 92 // The stored type 92 // The stored type 93 93 94 G4Cache(); 94 G4Cache(); 95 // Default constructor 95 // Default constructor 96 96 97 G4Cache(const value_type& v); 97 G4Cache(const value_type& v); 98 // Construct cache object with initial value 98 // Construct cache object with initial value 99 99 100 virtual ~G4Cache(); 100 virtual ~G4Cache(); 101 // Default destructor 101 // Default destructor 102 102 103 inline value_type& Get() const; 103 inline value_type& Get() const; 104 // Gets reference to cached value of this th 104 // Gets reference to cached value of this threads 105 105 106 inline void Put(const value_type& val) const 106 inline void Put(const value_type& val) const; 107 // Sets this thread cached value to val 107 // Sets this thread cached value to val 108 108 109 inline value_type Pop(); 109 inline value_type Pop(); 110 // Gets copy of cached value 110 // Gets copy of cached value 111 111 112 G4Cache(const G4Cache& rhs); 112 G4Cache(const G4Cache& rhs); 113 G4Cache& operator=(const G4Cache& rhs); 113 G4Cache& operator=(const G4Cache& rhs); 114 114 115 protected: 115 protected: 116 const G4int& GetId() const { return id; } 116 const G4int& GetId() const { return id; } 117 117 118 private: 118 private: 119 G4int id; 119 G4int id; 120 mutable G4CacheReference<value_type> theCach 120 mutable G4CacheReference<value_type> theCache; 121 static std::atomic<unsigned int> instancesct 121 static std::atomic<unsigned int> instancesctr; 122 static std::atomic<unsigned int> dstrctr; 122 static std::atomic<unsigned int> dstrctr; 123 123 124 inline value_type& GetCache() const 124 inline value_type& GetCache() const 125 { 125 { 126 theCache.Initialize(id); 126 theCache.Initialize(id); 127 return theCache.GetCache(id); 127 return theCache.GetCache(id); 128 } 128 } 129 }; 129 }; 130 130 131 // A vector version of the cache. Implements v 131 // A vector version of the cache. Implements vector interface. 132 // Can be used directly as a std::vector would 132 // Can be used directly as a std::vector would be used. 133 // 133 // 134 template <class VALTYPE> 134 template <class VALTYPE> 135 class G4VectorCache : public G4Cache<std::vect 135 class G4VectorCache : public G4Cache<std::vector<VALTYPE>> 136 { 136 { 137 public: 137 public: 138 // Some useful definitions 138 // Some useful definitions 139 // 139 // 140 using value_type = VALTYPE; 140 using value_type = VALTYPE; 141 using vector_type = typename std::vector<val 141 using vector_type = typename std::vector<value_type>; 142 using size_type = typename vector_type::size 142 using size_type = typename vector_type::size_type; 143 using iterator = typename vector_type::itera 143 using iterator = typename vector_type::iterator; 144 using const_iterator = typename vector_type: 144 using const_iterator = typename vector_type::const_iterator; 145 145 146 G4VectorCache(); 146 G4VectorCache(); 147 // Default constructor 147 // Default constructor 148 148 149 G4VectorCache(G4int nElems); 149 G4VectorCache(G4int nElems); 150 // Creates a vector cache of nElems elements 150 // Creates a vector cache of nElems elements 151 151 152 G4VectorCache(G4int nElems, value_type* vals 152 G4VectorCache(G4int nElems, value_type* vals); 153 // Creates a vector cache with elements from 153 // Creates a vector cache with elements from an array 154 154 155 virtual ~G4VectorCache(); 155 virtual ~G4VectorCache(); 156 // Default destructor 156 // Default destructor 157 157 158 // Interface with functionalities of similar 158 // Interface with functionalities of similar name of std::vector 159 // 159 // 160 inline void Push_back(const value_type& val) 160 inline void Push_back(const value_type& val); 161 inline value_type Pop_back(); 161 inline value_type Pop_back(); 162 inline value_type& operator[](const G4int& i 162 inline value_type& operator[](const G4int& idx); 163 inline iterator Begin(); 163 inline iterator Begin(); 164 inline iterator End(); 164 inline iterator End(); 165 inline void Clear(); 165 inline void Clear(); 166 inline size_type Size() { return G4Cache<vec 166 inline size_type Size() { return G4Cache<vector_type>::Get().size(); } 167 // Needs to be here for a VC9 compilation p 167 // Needs to be here for a VC9 compilation problem 168 }; 168 }; 169 169 170 // a Map version of the cache. Implements std: 170 // a Map version of the cache. Implements std::map interface. 171 // Can be used directly as a std::map would be 171 // Can be used directly as a std::map would be used. 172 // KEYTYPE being the key type and VALTYPE the 172 // KEYTYPE being the key type and VALTYPE the value type. 173 // 173 // 174 template <class KEYTYPE, class VALTYPE> 174 template <class KEYTYPE, class VALTYPE> 175 class G4MapCache : public G4Cache<std::map<KEY 175 class G4MapCache : public G4Cache<std::map<KEYTYPE, VALTYPE>> 176 { 176 { 177 public: 177 public: 178 // Some useful definitions 178 // Some useful definitions 179 // 179 // 180 using key_type = KEYTYPE; 180 using key_type = KEYTYPE; 181 using value_type = VALTYPE; 181 using value_type = VALTYPE; 182 using map_type = typename std::map<key_type, 182 using map_type = typename std::map<key_type, value_type>; 183 using size_type = typename map_type::size_ty 183 using size_type = typename map_type::size_type; 184 using iterator = typename map_type::iterator 184 using iterator = typename map_type::iterator; 185 using const_iterator = typename map_type::co 185 using const_iterator = typename map_type::const_iterator; 186 186 187 virtual ~G4MapCache(); 187 virtual ~G4MapCache(); 188 // Default destructor 188 // Default destructor 189 189 190 inline G4bool Has(const key_type& k); 190 inline G4bool Has(const key_type& k); 191 // Returns true if map contains element corr 191 // Returns true if map contains element corresponding to key k 192 192 193 // Interface with functionalities of similar 193 // Interface with functionalities of similar name of std::map 194 // 194 // 195 inline std::pair<iterator, G4bool> Insert(co 195 inline std::pair<iterator, G4bool> Insert(const key_type& k, 196 co 196 const value_type& v); 197 inline iterator Begin(); 197 inline iterator Begin(); 198 inline iterator End(); 198 inline iterator End(); 199 inline iterator Find(const key_type& k); 199 inline iterator Find(const key_type& k); 200 inline value_type& Get(const key_type& k); 200 inline value_type& Get(const key_type& k); 201 inline size_type Erase(const key_type& k); 201 inline size_type Erase(const key_type& k); 202 inline value_type& operator[](const key_type 202 inline value_type& operator[](const key_type& k); 203 inline size_type Size() { return G4Cache<map 203 inline size_type Size() { return G4Cache<map_type>::Get().size(); } 204 // Needs to be here for a VC9 compilation p 204 // Needs to be here for a VC9 compilation problem 205 }; 205 }; 206 206 207 //========= Implementation: G4Cache<V> ======= 207 //========= Implementation: G4Cache<V> ==================================== 208 208 209 template <class V> 209 template <class V> 210 G4Cache<V>::G4Cache() 210 G4Cache<V>::G4Cache() 211 { 211 { 212 G4AutoLock l(G4TypeMutex<G4Cache<V>>()); 212 G4AutoLock l(G4TypeMutex<G4Cache<V>>()); 213 id = instancesctr++; 213 id = instancesctr++; 214 #ifdef g4cdebug 214 #ifdef g4cdebug 215 std::cout << "G4Cache id: " << id << std::en 215 std::cout << "G4Cache id: " << id << std::endl; 216 #endif 216 #endif 217 } 217 } 218 218 219 template <class V> 219 template <class V> 220 G4Cache<V>::G4Cache(const G4Cache<V>& rhs) 220 G4Cache<V>::G4Cache(const G4Cache<V>& rhs) 221 { 221 { 222 // Copy is special, we need to copy the cont 222 // Copy is special, we need to copy the content 223 // of the cache, not the cache object 223 // of the cache, not the cache object 224 224 225 if(this == &rhs) 225 if(this == &rhs) 226 return; 226 return; 227 G4AutoLock l(G4TypeMutex<G4Cache<V>>()); 227 G4AutoLock l(G4TypeMutex<G4Cache<V>>()); 228 id = instancesctr++; 228 id = instancesctr++; 229 229 230 // Force copy of cached data 230 // Force copy of cached data 231 // 231 // 232 V aCopy = rhs.GetCache(); 232 V aCopy = rhs.GetCache(); 233 Put(aCopy); 233 Put(aCopy); 234 234 235 #ifdef g4cdebug 235 #ifdef g4cdebug 236 std::cout << "Copy constructor with id: " << 236 std::cout << "Copy constructor with id: " << id << std::endl; 237 #endif 237 #endif 238 } 238 } 239 239 240 template <class V> 240 template <class V> 241 G4Cache<V>& G4Cache<V>::operator=(const G4Cach 241 G4Cache<V>& G4Cache<V>::operator=(const G4Cache<V>& rhs) 242 { 242 { 243 if(this == &rhs) 243 if(this == &rhs) 244 return *this; 244 return *this; 245 245 246 // Force copy of cached data 246 // Force copy of cached data 247 // 247 // 248 V aCopy = rhs.GetCache(); 248 V aCopy = rhs.GetCache(); 249 Put(aCopy); 249 Put(aCopy); 250 250 251 #ifdef g4cdebug 251 #ifdef g4cdebug 252 std::cout << "Assignement operator with id: 252 std::cout << "Assignement operator with id: " << id << std::endl; 253 #endif 253 #endif 254 return *this; 254 return *this; 255 } 255 } 256 256 257 template <class V> 257 template <class V> 258 G4Cache<V>::G4Cache(const V& v) 258 G4Cache<V>::G4Cache(const V& v) 259 { 259 { 260 G4AutoLock l(G4TypeMutex<G4Cache<V>>()); 260 G4AutoLock l(G4TypeMutex<G4Cache<V>>()); 261 id = instancesctr++; 261 id = instancesctr++; 262 Put(v); 262 Put(v); 263 263 264 #ifdef g4cdebug 264 #ifdef g4cdebug 265 std::cout << "G4Cache id: " << id << std::en 265 std::cout << "G4Cache id: " << id << std::endl; 266 #endif 266 #endif 267 } 267 } 268 268 269 template <class V> 269 template <class V> 270 G4Cache<V>::~G4Cache() 270 G4Cache<V>::~G4Cache() 271 { 271 { 272 #ifdef g4cdebug 272 #ifdef g4cdebug 273 std::cout << "~G4Cache id: " << id << std::e 273 std::cout << "~G4Cache id: " << id << std::endl; 274 #endif 274 #endif 275 // don't automatically lock --> wait until w 275 // don't automatically lock --> wait until we can catch an error 276 // without scoping the G4AutoLock 276 // without scoping the G4AutoLock 277 // 277 // 278 G4AutoLock l(G4TypeMutex<G4Cache<V>>(), std: 278 G4AutoLock l(G4TypeMutex<G4Cache<V>>(), std::defer_lock); 279 279 280 // sometimes the mutex is unavailable in des 280 // sometimes the mutex is unavailable in destructors so 281 // try to lock the associated mutex, but cat 281 // try to lock the associated mutex, but catch if it fails 282 try 282 try 283 { 283 { 284 // a system_error in lock means that the m 284 // a system_error in lock means that the mutex is unavailable 285 // we want to throw the error that comes f 285 // we want to throw the error that comes from locking an unavailable 286 // mutex so that we know there is a memory 286 // mutex so that we know there is a memory leak 287 // if the mutex is valid, this will hold u 287 // if the mutex is valid, this will hold until the other thread finishes 288 // 288 // 289 l.lock(); 289 l.lock(); 290 } catch(std::system_error& e) 290 } catch(std::system_error& e) 291 { 291 { 292 // the error that comes from locking an un 292 // the error that comes from locking an unavailable mutex 293 #ifdef G4VERBOSE 293 #ifdef G4VERBOSE 294 G4cout << "Non-critical error: mutex lock 294 G4cout << "Non-critical error: mutex lock failure in ~G4Cache<" 295 << typeid(V).name() << ">. " << G4e 295 << typeid(V).name() << ">. " << G4endl 296 << "If the RunManagerKernel has bee 296 << "If the RunManagerKernel has been deleted, it failed to " 297 << "delete an allocated resource" < 297 << "delete an allocated resource" << G4endl 298 << "and this destructor is being ca 298 << "and this destructor is being called after the statics " 299 << "were destroyed." << G4endl; 299 << "were destroyed." << G4endl; 300 G4cout << "Exception: [code: " << e.code() 300 G4cout << "Exception: [code: " << e.code() << "] caught: " << e.what() 301 << G4endl; 301 << G4endl; 302 #endif 302 #endif 303 } 303 } 304 ++dstrctr; 304 ++dstrctr; 305 G4bool last = (dstrctr == instancesctr); 305 G4bool last = (dstrctr == instancesctr); 306 theCache.Destroy(id, last); 306 theCache.Destroy(id, last); 307 if(last) 307 if(last) 308 { 308 { 309 instancesctr.store(0); 309 instancesctr.store(0); 310 dstrctr.store(0); 310 dstrctr.store(0); 311 } 311 } 312 } 312 } 313 313 314 template <class V> 314 template <class V> 315 V& G4Cache<V>::Get() const 315 V& G4Cache<V>::Get() const 316 { 316 { 317 return GetCache(); 317 return GetCache(); 318 } 318 } 319 319 320 template <class V> 320 template <class V> 321 void G4Cache<V>::Put(const V& val) const 321 void G4Cache<V>::Put(const V& val) const 322 { 322 { 323 GetCache() = val; 323 GetCache() = val; 324 } 324 } 325 325 326 // Should here remove from cache element? 326 // Should here remove from cache element? 327 template <class V> 327 template <class V> 328 V G4Cache<V>::Pop() 328 V G4Cache<V>::Pop() 329 { 329 { 330 return GetCache(); 330 return GetCache(); 331 } 331 } 332 332 333 template <class V> 333 template <class V> 334 std::atomic<unsigned int> G4Cache<V>::instance 334 std::atomic<unsigned int> G4Cache<V>::instancesctr(0); 335 335 336 template <class V> 336 template <class V> 337 std::atomic<unsigned int> G4Cache<V>::dstrctr( 337 std::atomic<unsigned int> G4Cache<V>::dstrctr(0); 338 338 339 //========== Implementation: G4VectorCache<V> 339 //========== Implementation: G4VectorCache<V> =========================== 340 340 341 template <class V> 341 template <class V> 342 G4VectorCache<V>::G4VectorCache() = default; 342 G4VectorCache<V>::G4VectorCache() = default; 343 343 344 template <class V> 344 template <class V> 345 G4VectorCache<V>::~G4VectorCache() 345 G4VectorCache<V>::~G4VectorCache() 346 { 346 { 347 #ifdef g4cdebug 347 #ifdef g4cdebug 348 std::cout << "~G4VectorCache " 348 std::cout << "~G4VectorCache " 349 << G4Cache<G4VectorCache<V>::vecto 349 << G4Cache<G4VectorCache<V>::vector_type>::GetId() 350 << " with size: " << Size() << "-> 350 << " with size: " << Size() << "->"; 351 for(size_type i = 0; i < Size(); ++i) 351 for(size_type i = 0; i < Size(); ++i) 352 std::cout << operator[](i) << ","; 352 std::cout << operator[](i) << ","; 353 std::cout << "<-" << std::endl; 353 std::cout << "<-" << std::endl; 354 #endif 354 #endif 355 } 355 } 356 356 357 template <class V> 357 template <class V> 358 G4VectorCache<V>::G4VectorCache(G4int nElems) 358 G4VectorCache<V>::G4VectorCache(G4int nElems) 359 { 359 { 360 vector_type& cc = G4Cache<vector_type>::Get( 360 vector_type& cc = G4Cache<vector_type>::Get(); 361 cc.resize(nElems); 361 cc.resize(nElems); 362 } 362 } 363 363 364 template <class V> 364 template <class V> 365 G4VectorCache<V>::G4VectorCache(G4int nElems, 365 G4VectorCache<V>::G4VectorCache(G4int nElems, V* vals) 366 { 366 { 367 vector_type& cc = G4Cache<vector_type>::Get( 367 vector_type& cc = G4Cache<vector_type>::Get(); 368 cc.resize(nElems); 368 cc.resize(nElems); 369 for(G4int idx = 0; idx < nElems; ++idx) 369 for(G4int idx = 0; idx < nElems; ++idx) 370 cc[idx] = vals[idx]; 370 cc[idx] = vals[idx]; 371 } 371 } 372 372 373 template <class V> 373 template <class V> 374 void G4VectorCache<V>::Push_back(const V& val) 374 void G4VectorCache<V>::Push_back(const V& val) 375 { 375 { 376 G4Cache<vector_type>::Get().push_back(val); 376 G4Cache<vector_type>::Get().push_back(val); 377 } 377 } 378 378 379 template <class V> 379 template <class V> 380 V G4VectorCache<V>::Pop_back() 380 V G4VectorCache<V>::Pop_back() 381 { 381 { 382 vector_type& cc = G4Cache<vector_type>::Get( 382 vector_type& cc = G4Cache<vector_type>::Get(); 383 value_type val = cc[cc.size() - 1]; 383 value_type val = cc[cc.size() - 1]; 384 cc.pop_back(); 384 cc.pop_back(); 385 return val; 385 return val; 386 } 386 } 387 387 388 template <class V> 388 template <class V> 389 V& G4VectorCache<V>::operator[](const G4int& i 389 V& G4VectorCache<V>::operator[](const G4int& idx) 390 { 390 { 391 vector_type& cc = G4Cache<vector_type>::Get( 391 vector_type& cc = G4Cache<vector_type>::Get(); 392 return cc[idx]; 392 return cc[idx]; 393 } 393 } 394 394 395 template <class V> 395 template <class V> 396 typename G4VectorCache<V>::iterator G4VectorCa 396 typename G4VectorCache<V>::iterator G4VectorCache<V>::Begin() 397 { 397 { 398 return G4Cache<vector_type>::Get().begin(); 398 return G4Cache<vector_type>::Get().begin(); 399 } 399 } 400 400 401 template <class V> 401 template <class V> 402 typename G4VectorCache<V>::iterator G4VectorCa 402 typename G4VectorCache<V>::iterator G4VectorCache<V>::End() 403 { 403 { 404 return G4Cache<vector_type>::Get().end(); 404 return G4Cache<vector_type>::Get().end(); 405 } 405 } 406 406 407 template <class V> 407 template <class V> 408 void G4VectorCache<V>::Clear() 408 void G4VectorCache<V>::Clear() 409 { 409 { 410 G4Cache<vector_type>::Get().clear(); 410 G4Cache<vector_type>::Get().clear(); 411 } 411 } 412 412 413 // template<class V> 413 // template<class V> 414 // typename G4VectorCache<V>::size_type G4Vect 414 // typename G4VectorCache<V>::size_type G4VectorCache<V>::Size() 415 //{ 415 //{ 416 // return G4Cache<vector_type>::Get().size( 416 // return G4Cache<vector_type>::Get().size(); 417 //} 417 //} 418 418 419 //======== Implementation: G4MapType<K,V> ==== 419 //======== Implementation: G4MapType<K,V> =========================== 420 420 421 template <class K, class V> 421 template <class K, class V> 422 G4MapCache<K, V>::~G4MapCache() 422 G4MapCache<K, V>::~G4MapCache() 423 { 423 { 424 #ifdef g4cdebug 424 #ifdef g4cdebug 425 std::cout << "~G4MacCache " << G4Cache<map_t 425 std::cout << "~G4MacCache " << G4Cache<map_type>::GetId() 426 << " with size: " << Size() << "-> 426 << " with size: " << Size() << "->"; 427 for(iterator it = Begin(); it != End(); ++it 427 for(iterator it = Begin(); it != End(); ++it) 428 std::cout << it->first << ":" << it->secon 428 std::cout << it->first << ":" << it->second << ","; 429 std::cout << "<-" << std::endl; 429 std::cout << "<-" << std::endl; 430 #endif 430 #endif 431 } 431 } 432 432 433 template <class K, class V> 433 template <class K, class V> 434 std::pair<typename G4MapCache<K, V>::iterator, 434 std::pair<typename G4MapCache<K, V>::iterator, G4bool> G4MapCache<K, V>::Insert( 435 const K& k, const V& v) 435 const K& k, const V& v) 436 { 436 { 437 return G4Cache<map_type>::Get().insert(std:: 437 return G4Cache<map_type>::Get().insert(std::pair<key_type, value_type>(k, v)); 438 } 438 } 439 439 440 // template<class K, class V> 440 // template<class K, class V> 441 // typename G4MapCache<K,V>::size_type G4MapCa 441 // typename G4MapCache<K,V>::size_type G4MapCache<K,V>::Size() 442 //{ 442 //{ 443 // return G4Cache<map_type>::Get().size(); 443 // return G4Cache<map_type>::Get().size(); 444 //} 444 //} 445 445 446 template <class K, class V> 446 template <class K, class V> 447 typename G4MapCache<K, V>::iterator G4MapCache 447 typename G4MapCache<K, V>::iterator G4MapCache<K, V>::Begin() 448 { 448 { 449 return G4Cache<map_type>::Get().begin(); 449 return G4Cache<map_type>::Get().begin(); 450 } 450 } 451 template <class K, class V> 451 template <class K, class V> 452 typename G4MapCache<K, V>::iterator G4MapCache 452 typename G4MapCache<K, V>::iterator G4MapCache<K, V>::End() 453 { 453 { 454 return G4Cache<map_type>::Get().end(); 454 return G4Cache<map_type>::Get().end(); 455 } 455 } 456 456 457 template <class K, class V> 457 template <class K, class V> 458 typename G4MapCache<K, V>::iterator G4MapCache 458 typename G4MapCache<K, V>::iterator G4MapCache<K, V>::Find(const K& k) 459 { 459 { 460 return G4Cache<map_type>::Get().find(k); 460 return G4Cache<map_type>::Get().find(k); 461 } 461 } 462 462 463 template <class K, class V> 463 template <class K, class V> 464 G4bool G4MapCache<K, V>::Has(const K& k) 464 G4bool G4MapCache<K, V>::Has(const K& k) 465 { 465 { 466 return (Find(k) != End()); 466 return (Find(k) != End()); 467 } 467 } 468 468 469 template <class K, class V> 469 template <class K, class V> 470 V& G4MapCache<K, V>::Get(const K& k) 470 V& G4MapCache<K, V>::Get(const K& k) 471 { 471 { 472 return Find(k)->second; 472 return Find(k)->second; 473 } 473 } 474 474 475 template <class K, class V> 475 template <class K, class V> 476 typename G4MapCache<K, V>::size_type G4MapCach 476 typename G4MapCache<K, V>::size_type G4MapCache<K, V>::Erase(const K& k) 477 { 477 { 478 return G4Cache<map_type>::Get().erase(k); 478 return G4Cache<map_type>::Get().erase(k); 479 } 479 } 480 480 481 template <class K, class V> 481 template <class K, class V> 482 V& G4MapCache<K, V>::operator[](const K& k) 482 V& G4MapCache<K, V>::operator[](const K& k) 483 { 483 { 484 return (G4Cache<map_type>::Get())[k]; 484 return (G4Cache<map_type>::Get())[k]; 485 } 485 } 486 486 487 #endif 487 #endif 488 488