Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/global/management/include/G4Cache.hh

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

Diff markup

Differences between /global/management/include/G4Cache.hh (Version 11.3.0) and /global/management/include/G4Cache.hh (Version 11.1.1)


  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