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