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