File indexing completed on 2025-01-18 09:59:10
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 #ifndef G4THitsMap_h
0029 #define G4THitsMap_h 1
0030
0031 #include "G4THitsCollection.hh"
0032 #include "globals.hh"
0033
0034 #include <map>
0035 #include <unordered_map>
0036 #include <type_traits>
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048 template <typename T, typename Map_t = std::map<G4int, T*>>
0049 class G4VTHitsMap : public G4HitsCollection
0050 {
0051 private:
0052 using mmap_t = std::multimap<G4int, T *>;
0053 using pair_t = std::pair<G4int, T *>;
0054 using uommap_t = std::unordered_multimap<G4int, T *>;
0055
0056 #define is_same_t(_Tp, _Up) std::is_same<_Tp, _Up>::value
0057 #define is_multimap_t(_Mp) std::is_same<_Mp, mmap_t>::value
0058 #define is_uommap_t(_Mp) std::is_same<_Mp, uommap_t>::value
0059 #define is_mmap_t(_Mp) (is_multimap_t(_Mp) || is_uommap_t(_Mp))
0060 #define is_fundamental_t(_Tp) std::is_fundamental<_Tp>::value
0061
0062 template <bool _Bp, typename _Tp = void>
0063 using enable_if_t = typename std::enable_if<_Bp, _Tp>::type;
0064
0065
0066 template <typename U = T, enable_if_t<is_fundamental_t(U), G4int> = 0>
0067 T* allocate() const
0068 {
0069 return new T(0.);
0070 }
0071
0072
0073
0074 template <typename U = T, enable_if_t<! is_fundamental_t(U), G4int> = 0>
0075 T* allocate() const
0076 {
0077 return new T();
0078 }
0079
0080 public:
0081 using this_type = G4VTHitsMap<T, Map_t>;
0082 using value_type = T;
0083 using map_type = Map_t;
0084 using iterator = typename map_type::iterator;
0085 using const_iterator = typename map_type::const_iterator;
0086
0087 public:
0088
0089 G4VTHitsMap();
0090
0091 G4VTHitsMap(G4String detName, G4String colNam);
0092
0093 ~G4VTHitsMap() override;
0094
0095 G4bool operator==(const G4VTHitsMap<T, Map_t>& right) const;
0096
0097
0098
0099
0100
0101 template <typename U, typename MapU_t>
0102 this_type& operator+=(const G4VTHitsMap<U, MapU_t>& right) const
0103 {
0104 MapU_t* aHitsMap = right.GetMap();
0105 for (auto itr = aHitsMap->begin(); itr != aHitsMap->end(); ++itr)
0106 add<U, map_type>(itr->first, *(itr->second));
0107 return (this_type&)(*this);
0108 }
0109
0110
0111 public:
0112 void DrawAllHits() override;
0113 void PrintAllHits() override;
0114
0115
0116
0117 public:
0118
0119 inline Map_t* GetContainer() const { return (Map_t*)theCollection; }
0120
0121 inline typename Map_t::size_type size() { return GetContainer()->size(); }
0122
0123 inline typename Map_t::size_type GetIndex(iterator itr) { return itr->first; }
0124
0125 inline typename Map_t::size_type GetIndex(const_iterator itr) const { return itr->first; }
0126
0127 template <typename MapU_t = Map_t, enable_if_t<! is_mmap_t(MapU_t), G4int> = 0>
0128 inline T* GetObject(G4int idx) const
0129 {
0130 return (GetContainer()->count(idx) != 0) ? (*GetContainer())[idx] : nullptr;
0131 }
0132
0133 template <typename MapU_t = Map_t, enable_if_t<is_mmap_t(MapU_t), G4int> = 0>
0134 inline T* GetObject(G4int idx) const
0135 {
0136 return (GetContainer()->count(idx) != 0) ? GetContainer()->find(idx)->second : nullptr;
0137 }
0138
0139 inline T* GetObject(iterator itr) const { return itr->second; }
0140
0141 inline const T* GetObject(const_iterator itr) const { return itr->second; }
0142
0143 iterator begin() { return GetContainer()->begin(); }
0144 iterator end() { return GetContainer()->end(); }
0145 const_iterator begin() const { return GetContainer()->begin(); }
0146 const_iterator end() const { return GetContainer()->end(); }
0147 const_iterator cbegin() const { return GetContainer()->cbegin(); }
0148 const_iterator cend() const { return GetContainer()->cend(); }
0149
0150 public:
0151
0152 inline Map_t* GetMap() const { return (Map_t*)theCollection; }
0153
0154
0155 inline size_t entries() const { return ((Map_t*)theCollection)->size(); }
0156
0157 inline void clear();
0158
0159 public:
0160 G4VHit* GetHit(size_t) const override { return nullptr; }
0161 size_t GetSize() const override { return ((Map_t*)theCollection)->size(); }
0162
0163 public:
0164
0165
0166
0167
0168
0169
0170
0171
0172 template <typename U = T, typename MapU_t = Map_t,
0173 enable_if_t<is_same_t(U, T) && ! is_mmap_t(MapU_t), G4int> = 0>
0174 size_t add(const G4int& key, U*& aHit) const
0175 {
0176 map_type* theHitsMap = GetMap();
0177 if (theHitsMap->find(key) == theHitsMap->end())
0178 theHitsMap->insert(pair_t(key, new T(*aHit)));
0179 else
0180 *theHitsMap->find(key)->second += *aHit;
0181 return theHitsMap->size();
0182 }
0183
0184
0185
0186 template <typename U = T, typename MapU_t = Map_t,
0187 enable_if_t<(is_same_t(U, T) && is_mmap_t(MapU_t)), G4int> = 0>
0188 size_t add(const G4int& key, U*& aHit) const
0189 {
0190 map_type* theHitsMap = GetMap();
0191 theHitsMap->insert(pair_t(key, aHit));
0192 return theHitsMap->size();
0193 }
0194
0195
0196
0197
0198 template <typename U = T, typename MapU_t = Map_t,
0199 enable_if_t<(! is_same_t(U, T) && is_mmap_t(MapU_t)), G4int> = 0>
0200 size_t add(const G4int& key, U*& aHit) const
0201 {
0202 map_type* theHitsMap = GetMap();
0203 T* hit = allocate();
0204 *hit += *aHit;
0205 theHitsMap->insert(pair_t(key, hit));
0206 return theHitsMap->size();
0207 }
0208
0209 public:
0210
0211
0212
0213
0214
0215
0216 template <typename U = T, typename MapU_t = Map_t,
0217 enable_if_t<(is_same_t(U, T) && ! is_mmap_t(MapU_t)), G4int> = 0>
0218 size_t add(const G4int& key, U& aHit) const
0219 {
0220 map_type* theHitsMap = GetMap();
0221 if (theHitsMap->find(key) == theHitsMap->end())
0222 theHitsMap->insert(pair_t(key, new T(aHit)));
0223 else
0224 *theHitsMap->find(key)->second += aHit;
0225 return theHitsMap->size();
0226 }
0227
0228
0229
0230
0231 template <typename U = T, typename MapU_t = Map_t,
0232 enable_if_t<(! is_same_t(U, T) && ! is_mmap_t(MapU_t)), G4int> = 0>
0233 size_t add(const G4int& key, U& aHit) const
0234 {
0235 map_type* theHitsMap = GetMap();
0236 if (theHitsMap->find(key) == theHitsMap->end()) theHitsMap->insert(pair_t(key, allocate()));
0237 *theHitsMap->find(key)->second += aHit;
0238 return theHitsMap->size();
0239 }
0240
0241
0242
0243 template <typename U = T, typename MapU_t = Map_t,
0244 enable_if_t<(is_same_t(U, T) && is_mmap_t(MapU_t)), G4int> = 0>
0245 size_t add(const G4int& key, U& aHit) const
0246 {
0247 map_type* theHitsMap = GetMap();
0248 theHitsMap->insert(pair_t(key, new T(aHit)));
0249 return theHitsMap->size();
0250 }
0251
0252
0253
0254
0255 template <typename U = T, typename MapU_t = Map_t,
0256 enable_if_t<(! is_same_t(U, T) && is_mmap_t(MapU_t)), G4int> = 0>
0257 size_t add(const G4int& key, U& aHit) const
0258 {
0259 map_type* theHitsMap = GetMap();
0260 T* hit = allocate();
0261 *hit += aHit;
0262 theHitsMap->insert(pair_t(key, hit));
0263 return theHitsMap->size();
0264 }
0265
0266
0267 public:
0268
0269
0270
0271
0272
0273
0274 template <typename U = T, typename MapU_t = Map_t,
0275 enable_if_t<(is_same_t(U, T) && ! is_mmap_t(MapU_t)), G4int> = 0>
0276 inline size_t set(const G4int& key, U*& aHit) const
0277 {
0278 map_type* theHitsMap = GetMap();
0279 if (theHitsMap->find(key) != theHitsMap->end()) delete theHitsMap->find(key)->second;
0280 theHitsMap->find(key)->second = aHit;
0281 return theHitsMap->size();
0282 }
0283
0284
0285
0286 template <typename U = T, typename MapU_t = Map_t,
0287 enable_if_t<(is_same_t(U, T) && is_mmap_t(MapU_t)), G4int> = 0>
0288 inline size_t set(const G4int& key, U*& aHit) const
0289 {
0290 map_type* theHitsMap = GetMap();
0291 if (theHitsMap->find(key) != theHitsMap->end())
0292 theHitsMap->insert(pair_t(key, aHit));
0293 else {
0294 delete theHitsMap->find(key)->second;
0295 theHitsMap->find(key)->second = aHit;
0296 }
0297 return theHitsMap->size();
0298 }
0299
0300
0301
0302 template <typename U = T, typename MapU_t = Map_t,
0303 enable_if_t<(! is_same_t(U, T) && ! is_mmap_t(MapU_t)), G4int> = 0>
0304 inline size_t set(const G4int& key, U*& aHit) const
0305 {
0306 map_type* theHitsMap = GetMap();
0307 T* hit = nullptr;
0308 if (theHitsMap->find(key) == theHitsMap->end())
0309 theHitsMap->insert(std::make_pair(key, hit = allocate()));
0310 else
0311 hit = theHitsMap->find(key)->second;
0312 *hit += *aHit;
0313 return theHitsMap->size();
0314 }
0315
0316
0317
0318 template <typename U = T, typename MapU_t = Map_t,
0319 enable_if_t<(! is_same_t(U, T) && is_mmap_t(MapU_t)), G4int> = 0>
0320 inline size_t set(const G4int& key, U*& aHit) const
0321 {
0322 map_type* theHitsMap = GetMap();
0323 T* hit = allocate();
0324 *hit += *aHit;
0325 if (theHitsMap->find(key) != theHitsMap->end())
0326 theHitsMap->insert(pair_t(key, hit));
0327 else {
0328 delete theHitsMap->find(key)->second;
0329 theHitsMap->find(key)->second = hit;
0330 }
0331 return theHitsMap->size();
0332 }
0333
0334
0335 public:
0336
0337
0338
0339
0340
0341
0342 template <typename U = T, typename MapU_t = Map_t,
0343 enable_if_t<(is_same_t(U, T) && ! is_mmap_t(MapU_t)), G4int> = 0>
0344 inline size_t set(const G4int& key, U& aHit) const
0345 {
0346 map_type* theHitsMap = GetMap();
0347 T* hit = nullptr;
0348 if (theHitsMap->find(key) != theHitsMap->end())
0349 hit = theHitsMap->find(key)->second;
0350 else
0351 theHitsMap->insert(pair_t(key, hit = allocate()));
0352 *hit = aHit;
0353 return theHitsMap->size();
0354 }
0355
0356
0357
0358 template <typename U = T, typename MapU_t = Map_t,
0359 enable_if_t<(is_same_t(U, T) && is_mmap_t(MapU_t)), G4int> = 0>
0360 inline size_t set(const G4int& key, U& aHit) const
0361 {
0362 map_type* theHitsMap = GetMap();
0363 if (theHitsMap->find(key) != theHitsMap->end())
0364 *theHitsMap->find(key)->second = aHit;
0365 else
0366 theHitsMap->insert(pair_t(key, new T(aHit)));
0367 return theHitsMap->size();
0368 }
0369
0370
0371
0372 template <typename U = T, typename MapU_t = Map_t,
0373 enable_if_t<(! is_same_t(U, T) && ! is_mmap_t(MapU_t)), G4int> = 0>
0374 inline size_t set(const G4int& key, U& aHit) const
0375 {
0376 map_type* theHitsMap = GetMap();
0377 T* hit = nullptr;
0378 if (theHitsMap->find(key) == theHitsMap->end())
0379 theHitsMap->insert(std::make_pair(key, hit = allocate()));
0380 else
0381 hit = theHitsMap->find(key)->second;
0382 *hit += aHit;
0383 return theHitsMap->size();
0384 }
0385
0386
0387
0388 template <typename U = T, typename MapU_t = Map_t,
0389 enable_if_t<(! is_same_t(U, T) && is_mmap_t(MapU_t)), G4int> = 0>
0390 inline size_t set(const G4int& key, U& aHit) const
0391 {
0392 map_type* theHitsMap = GetMap();
0393 T* hit = allocate();
0394 *hit += aHit;
0395 if (theHitsMap->find(key) != theHitsMap->end())
0396 *theHitsMap->find(key)->second = *hit;
0397 else
0398 theHitsMap->insert(pair_t(key, hit));
0399 return theHitsMap->size();
0400 }
0401
0402
0403 public:
0404
0405
0406
0407
0408
0409 template <typename MapU_t = Map_t, enable_if_t<! is_mmap_t(MapU_t), G4int> = 0>
0410 T* operator[](G4int key) const
0411 {
0412 map_type* theHitsMap = GetMap();
0413 if (theHitsMap->find(key) != theHitsMap->end()) return theHitsMap->find(key)->second;
0414 return nullptr;
0415 }
0416
0417 template <typename MapU_t = Map_t, enable_if_t<is_mmap_t(MapU_t), G4int> = 0>
0418 T* operator[](G4int key) const
0419 {
0420 #ifdef G4VERBOSE
0421 static bool _first = true;
0422 if (_first) {
0423 _first = false;
0424 G4Exception("G4THitsMap operator[]", "calling [] on multimap", JustWarning,
0425 "Returning the last matching entry");
0426 }
0427 #endif
0428 map_type* theHitsMap = GetMap();
0429 iterator itr = theHitsMap->find(key);
0430 if (itr != theHitsMap->end()) {
0431 std::advance(itr, theHitsMap->count(key) - 1);
0432 return itr->second;
0433 }
0434 return nullptr;
0435 }
0436
0437
0438 #undef is_same_t
0439 #undef is_multimap_t
0440 #undef is_uommap_t
0441 #undef is_mmap_t
0442 #undef is_fundamental_t
0443 };
0444
0445
0446
0447 template <typename T, typename Map_t>
0448 G4VTHitsMap<T, Map_t>::G4VTHitsMap()
0449 {
0450 theCollection = (void*)new Map_t;
0451 }
0452
0453
0454
0455 template <typename T, typename Map_t>
0456 G4VTHitsMap<T, Map_t>::G4VTHitsMap(G4String detName, G4String colNam)
0457 : G4HitsCollection(detName, colNam)
0458 {
0459 theCollection = (void*)new Map_t;
0460 }
0461
0462
0463
0464 template <typename T, typename Map_t>
0465 G4VTHitsMap<T, Map_t>::~G4VTHitsMap()
0466 {
0467 map_type* theHitsMap = GetMap();
0468 for (auto itr = theHitsMap->begin(); itr != theHitsMap->end(); ++itr)
0469 delete itr->second;
0470 delete theHitsMap;
0471 }
0472
0473
0474
0475 template <typename T, typename Map_t>
0476 G4bool G4VTHitsMap<T, Map_t>::operator==(const G4VTHitsMap<T, Map_t>& right) const
0477 {
0478 return (collectionName == right.collectionName);
0479 }
0480
0481
0482
0483 template <typename T, typename Map_t>
0484 void G4VTHitsMap<T, Map_t>::DrawAllHits()
0485 {
0486 ;
0487 }
0488
0489
0490
0491 template <typename T, typename Map_t>
0492 void G4VTHitsMap<T, Map_t>::PrintAllHits()
0493 {
0494 G4cout << "G4THitsMap " << SDname << " / " << collectionName << " --- " << entries() << " entries"
0495 << G4endl;
0496
0497
0498
0499
0500
0501
0502
0503
0504
0505
0506
0507
0508 }
0509
0510
0511
0512 template <typename T, typename Map_t>
0513 void G4VTHitsMap<T, Map_t>::clear()
0514 {
0515 Map_t* theHitsMap = GetMap();
0516 for (iterator itr = theHitsMap->begin(); itr != theHitsMap->end(); ++itr)
0517 delete itr->second;
0518 theHitsMap->clear();
0519 }
0520
0521
0522
0523
0524
0525
0526
0527
0528
0529 template <typename _Tp>
0530 class G4THitsMap : public G4VTHitsMap<_Tp, std::map<G4int, _Tp*>>
0531 {
0532 public:
0533 using parent_type = G4VTHitsMap<_Tp, std::map<G4int, _Tp *>>;
0534
0535 public:
0536 G4THitsMap() : parent_type() {}
0537 G4THitsMap(G4String detName, G4String colName) : parent_type(detName, colName) {}
0538
0539 using parent_type::operator+=;
0540 using parent_type::operator==;
0541 using parent_type::operator[];
0542 using parent_type::add;
0543 using parent_type::begin;
0544 using parent_type::cbegin;
0545 using parent_type::cend;
0546 using parent_type::clear;
0547 using parent_type::DrawAllHits;
0548 using parent_type::end;
0549 using parent_type::entries;
0550 using parent_type::GetHit;
0551 using parent_type::GetMap;
0552 using parent_type::GetSize;
0553 using parent_type::PrintAllHits;
0554 using parent_type::set;
0555 };
0556
0557
0558
0559 template <typename _Tp>
0560 class G4THitsMultiMap : public G4VTHitsMap<_Tp, std::multimap<G4int, _Tp*>>
0561 {
0562 public:
0563 using parent_type = G4VTHitsMap<_Tp, std::multimap<G4int, _Tp *>>;
0564
0565 public:
0566 G4THitsMultiMap() : parent_type() {}
0567 G4THitsMultiMap(G4String detName, G4String colName) : parent_type(detName, colName) {}
0568
0569 using parent_type::operator+=;
0570 using parent_type::operator==;
0571 using parent_type::operator[];
0572 using parent_type::add;
0573 using parent_type::begin;
0574 using parent_type::cbegin;
0575 using parent_type::cend;
0576 using parent_type::clear;
0577 using parent_type::DrawAllHits;
0578 using parent_type::end;
0579 using parent_type::entries;
0580 using parent_type::GetHit;
0581 using parent_type::GetMap;
0582 using parent_type::GetSize;
0583 using parent_type::PrintAllHits;
0584 using parent_type::set;
0585 };
0586
0587
0588
0589 template <typename _Tp>
0590 class G4THitsUnorderedMap : public G4VTHitsMap<_Tp, std::unordered_map<G4int, _Tp*>>
0591 {
0592 public:
0593 using parent_type = G4VTHitsMap<_Tp, std::unordered_map<G4int, _Tp *>>;
0594
0595 public:
0596 G4THitsUnorderedMap() : parent_type() {}
0597 G4THitsUnorderedMap(G4String detName, G4String colName) : parent_type(detName, colName) {}
0598
0599 using parent_type::operator+=;
0600 using parent_type::operator==;
0601 using parent_type::operator[];
0602 using parent_type::add;
0603 using parent_type::begin;
0604 using parent_type::cbegin;
0605 using parent_type::cend;
0606 using parent_type::clear;
0607 using parent_type::DrawAllHits;
0608 using parent_type::end;
0609 using parent_type::entries;
0610 using parent_type::GetHit;
0611 using parent_type::GetMap;
0612 using parent_type::GetSize;
0613 using parent_type::PrintAllHits;
0614 using parent_type::set;
0615 };
0616
0617
0618
0619 template <typename _Tp>
0620 class G4THitsUnorderedMultiMap : public G4VTHitsMap<_Tp, std::unordered_multimap<G4int, _Tp*>>
0621 {
0622 public:
0623 using parent_type = G4VTHitsMap<_Tp, std::unordered_multimap<G4int, _Tp *>>;
0624
0625 public:
0626 G4THitsUnorderedMultiMap() : parent_type() {}
0627 G4THitsUnorderedMultiMap(G4String detName, G4String colName) : parent_type(detName, colName) {}
0628
0629 using parent_type::operator+=;
0630 using parent_type::operator==;
0631 using parent_type::operator[];
0632 using parent_type::add;
0633 using parent_type::begin;
0634 using parent_type::cbegin;
0635 using parent_type::cend;
0636 using parent_type::clear;
0637 using parent_type::DrawAllHits;
0638 using parent_type::end;
0639 using parent_type::entries;
0640 using parent_type::GetHit;
0641 using parent_type::GetMap;
0642 using parent_type::GetSize;
0643 using parent_type::PrintAllHits;
0644 using parent_type::set;
0645 };
0646
0647
0648
0649 #endif