File indexing completed on 2025-01-18 09:58:00
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060 #ifndef G4CacheDetails_hh
0061 #define G4CacheDetails_hh
0062
0063 #include "G4Threading.hh"
0064 #include "globals.hh"
0065 #include <vector>
0066
0067
0068
0069 template <class VALTYPE>
0070 class G4CacheReference
0071 {
0072 public:
0073 inline void Initialize(unsigned int id);
0074
0075
0076 inline void Destroy(unsigned int id, G4bool last);
0077
0078
0079
0080 inline VALTYPE& GetCache(unsigned int id) const;
0081
0082
0083 private:
0084 using cache_container = std::vector<VALTYPE*>;
0085
0086
0087
0088
0089
0090 static cache_container*& cache();
0091 };
0092
0093
0094
0095
0096
0097 template <class VALTYPE>
0098 class G4CacheReference<VALTYPE*>
0099 {
0100 public:
0101 inline void Initialize(unsigned int id);
0102
0103 inline void Destroy(unsigned int id, G4bool last);
0104
0105 inline VALTYPE*& GetCache(unsigned int id) const;
0106
0107 private:
0108 using cache_container = std::vector<VALTYPE*>;
0109 static cache_container*& cache();
0110 };
0111
0112
0113
0114
0115 template <>
0116 class G4CacheReference<G4double>
0117 {
0118 public:
0119 inline void Initialize(unsigned int id);
0120
0121 inline void Destroy(unsigned int id, G4bool last);
0122
0123 inline G4double& GetCache(unsigned int id) const;
0124
0125 private:
0126 using cache_container = std::vector<G4double>;
0127 static G4GLOB_DLL cache_container*& cache();
0128 };
0129
0130
0131
0132
0133 template <class V>
0134 void G4CacheReference<V>::Initialize(unsigned int id)
0135 {
0136
0137 if(cache() == nullptr)
0138 {
0139 #ifdef g4cdebug
0140 std::cout << "Generic template container..." << std::endl;
0141 #endif
0142 cache() = new cache_container;
0143 }
0144 if(cache()->size() <= id)
0145 {
0146 cache()->resize(id + 1, static_cast<V*>(0));
0147 }
0148 if((*cache())[id] == 0)
0149 {
0150 (*cache())[id] = new V;
0151 }
0152 }
0153
0154 template <class V>
0155 void G4CacheReference<V>::Destroy(unsigned int id, G4bool last)
0156 {
0157 if(cache() != nullptr)
0158 {
0159 #ifdef g4cdebug
0160 std::cout << "V: Destroying element " << id << " is last? " << last
0161 << std::endl;
0162 #endif
0163 if(cache()->size() < id)
0164 {
0165 G4ExceptionDescription msg;
0166 msg << "Internal fatal error. Invalid G4Cache size (requested id: " << id
0167 << " but cache has size: " << cache()->size();
0168 msg << " Possibly client created G4Cache object in a thread and"
0169 << " tried to delete it from another thread!";
0170 G4Exception("G4CacheReference<V>::Destroy", "Cache001", FatalException,
0171 msg);
0172 return;
0173 }
0174 if(cache()->size() > id && (*cache())[id] != nullptr)
0175 {
0176 #ifdef g4cdebug
0177 std::cout << "V: Destroying element " << id
0178 << " size: " << cache()->size() << std::endl;
0179 #endif
0180 delete(*cache())[id];
0181 (*cache())[id] = nullptr;
0182 }
0183 if(last)
0184 {
0185 #ifdef g4cdebug
0186 std::cout << "V: Destroying LAST element!" << std::endl;
0187 #endif
0188 delete cache();
0189 cache() = nullptr;
0190 }
0191 }
0192 }
0193
0194 template <class V>
0195 V& G4CacheReference<V>::GetCache(unsigned int id) const
0196 {
0197 return *(cache()->operator[](id));
0198 }
0199
0200 template <class V>
0201 typename G4CacheReference<V>::cache_container*& G4CacheReference<V>::cache()
0202 {
0203 G4ThreadLocalStatic cache_container* _instance = nullptr;
0204 return _instance;
0205 }
0206
0207
0208
0209
0210 template <class V>
0211 void G4CacheReference<V*>::Initialize(unsigned int id)
0212 {
0213 if(cache() == nullptr)
0214 {
0215 #ifdef g4cdebug
0216 std::cout << "Pointer template container..." << std::endl;
0217 #endif
0218 cache() = new cache_container;
0219 }
0220 if(cache()->size() <= id)
0221 {
0222 cache()->resize(id + 1, static_cast<V*>(nullptr));
0223 }
0224 }
0225
0226 template <class V>
0227 inline void G4CacheReference<V*>::Destroy(unsigned int id, G4bool last)
0228 {
0229 if(cache() != nullptr)
0230 {
0231 #ifdef g4cdebug
0232 std::cout << "V*: Destroying element " << id << " is last? " << last
0233 << std::endl;
0234 #endif
0235 if(cache()->size() < id)
0236 {
0237 G4ExceptionDescription msg;
0238 msg << "Internal fatal error. Invalid G4Cache size (requested id: " << id
0239 << " but cache has size: " << cache()->size();
0240 msg << " Possibly client created G4Cache object in a thread and"
0241 << " tried to delete it from another thread!";
0242 G4Exception("G4CacheReference<V*>::Destroy", "Cache001", FatalException,
0243 msg);
0244 return;
0245 }
0246 if(cache()->size() > id && (*cache())[id] != nullptr)
0247 {
0248
0249
0250 #ifdef g4cdebug
0251 std::cout << "V*: Resetting element " << id
0252 << " size: " << cache()->size() << std::endl;
0253 #endif
0254 (*cache())[id] = nullptr;
0255 }
0256 if(last)
0257 {
0258 #ifdef g4cdebug
0259 std::cout << "V*: Deleting LAST element!" << std::endl;
0260 #endif
0261 delete cache();
0262 cache() = nullptr;
0263 }
0264 }
0265 }
0266
0267 template <class V>
0268 V*& G4CacheReference<V*>::GetCache(unsigned int id) const
0269 {
0270 return (cache()->operator[](id));
0271 }
0272
0273 template <class V>
0274 typename G4CacheReference<V*>::cache_container*& G4CacheReference<V*>::cache()
0275 {
0276 G4ThreadLocalStatic cache_container* _instance = nullptr;
0277 return _instance;
0278 }
0279
0280
0281
0282
0283 void G4CacheReference<G4double>::Initialize(unsigned int id)
0284 {
0285 if(cache() == nullptr)
0286 {
0287 #ifdef g4cdebug
0288 std::cout << "Specialized template for G4double container..." << std::endl;
0289 #endif
0290 cache() = new cache_container;
0291 }
0292 if(cache()->size() <= id)
0293 {
0294 cache()->resize(id + 1, static_cast<G4double>(0));
0295 }
0296 }
0297
0298 void G4CacheReference<G4double>::Destroy(unsigned int , G4bool last)
0299 {
0300 if(cache() != nullptr && last)
0301 {
0302 #ifdef g4cdebug
0303 std::cout << "DB: Destroying LAST element! Is it last? " << last
0304 << std::endl;
0305 #endif
0306 delete cache();
0307 cache() = nullptr;
0308 }
0309 }
0310
0311 G4double& G4CacheReference<G4double>::GetCache(unsigned int id) const
0312 {
0313 return cache()->operator[](id);
0314 }
0315
0316 #endif