Warning, file /include/Geant4/G4THitsMap.hh was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
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