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