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