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