Geant4 Cross Reference |
1 // 2 // ******************************************************************** 3 // * License and Disclaimer * 4 // * * 5 // * The Geant4 software is copyright of the Copyright Holders of * 6 // * the Geant4 Collaboration. It is provided under the terms and * 7 // * conditions of the Geant4 Software License, included in the file * 8 // * LICENSE and available at http://cern.ch/geant4/license . These * 9 // * include a list of copyright holders. * 10 // * * 11 // * Neither the authors of this software system, nor their employing * 12 // * institutes,nor the agencies providing financial support for this * 13 // * work make any representation or warranty, express or implied, * 14 // * regarding this software system or assume any liability for its * 15 // * use. Please see the license in the file LICENSE and URL above * 16 // * for the full disclaimer and the limitation of liability. * 17 // * * 18 // * This code implementation is the result of the scientific and * 19 // * technical work of the GEANT4 collaboration. * 20 // * By using, copying, modifying or distributing the software (or * 21 // * any work based on the software) you agree to acknowledge its * 22 // * use in resulting scientific publications, and indicate your * 23 // * acceptance of all terms of the Geant4 Software license. * 24 // ******************************************************************** 25 // 26 // 27 // Author: Mathieu Karamitros 28 29 // The code is developed in the framework of the ESA AO7146 30 // 31 // We would be very happy hearing from you, send us your feedback! :) 32 // 33 // In order for Geant4-DNA to be maintained and still open-source, 34 // article citations are crucial. 35 // If you use Geant4-DNA chemistry and you publish papers about your software, 36 // in addition to the general paper on Geant4-DNA: 37 // 38 // Int. J. Model. Simul. Sci. Comput. 1 (2010) 157–178 39 // 40 // we would be very happy if you could please also cite the following 41 // reference papers on chemistry: 42 // 43 // J. Comput. Phys. 274 (2014) 841-882 44 // Prog. Nucl. Sci. Tec. 2 (2011) 503-508 45 46 #pragma once 47 48 #include "globals.hh" 49 #include "G4ReferenceCountedHandle.hh" 50 #include <G4memory.hh> 51 #include <vector> 52 #include <set> 53 //#include "G4ManyFastLists.hh" 54 55 template<class OBJECT> 56 class G4FastList; 57 template<class OBJECT> 58 class G4FastList_Boundary; 59 template<typename OBJECT> 60 struct G4FastList_iterator; 61 template<typename OBJECT> 62 struct G4FastList_const_iterator; 63 template<typename OBJECT> 64 class G4ManyFastLists; 65 template<typename OBJECT> 66 struct G4ManyFastLists_iterator; 67 template<class OBJECT> 68 struct sortWatcher; 69 70 71 /** Comments : 72 * - A track cannot belong to two different track lists 73 * - Erase a given track is constant complexity 74 * - This development was thought to be used together with G4IT 75 */ 76 77 #ifndef TYPE_WRAPPER 78 #define TYPE_WRAPPER 79 template < typename T> 80 struct type_wrapper 81 { 82 using type = T; 83 }; 84 #endif 85 86 template<class LIST> 87 struct _ListRef 88 { 89 using traits_type = type_wrapper<LIST>; 90 using mli_traits_type = type_wrapper<G4ManyFastLists_iterator<typename LIST::object>>; 91 92 //#ifdef WIN32 93 // friend typename traits_type::type; 94 // friend typename traits_type::type::node; 95 // friend typename mli_traits_type::type; 96 ////#elif defined(__clang__) 97 //// friend T; 98 //// friend T::node; 99 //// friend G4ManyFastLists_iterator<traits_type::type::object>; 100 //#else 101 // friend class traits_type::type; 102 // friend class traits_type::type::node; 103 // friend class mli_traits_type::type; 104 //#endif 105 106 LIST* fpList; 107 108 // protected: 109 inline _ListRef(LIST* __list) : 110 fpList(__list) 111 { 112 ; 113 } 114 }; 115 116 /** 117 * G4FastListNode is the entity actually stored 118 * by the G4FastList. A G4FastListNode should 119 * belong only to one list. Also, an object 120 * should belong only to one list. 121 */ 122 123 template<class OBJECT> 124 class G4FastListNode 125 { 126 using ObjectW = type_wrapper<OBJECT>; 127 using LIST = G4FastList<typename ObjectW::type>; 128 // typedef type_wrapper<LIST> > ListW; 129 using ListW = type_wrapper<G4FastList<OBJECT>>; 130 // typedef type_wrapper<G4ManyFastLists<typename ObjectW::type> > ManyListsW; 131 using ManyListsW = type_wrapper<G4ManyFastLists<OBJECT>>; 132 // typedef type_wrapper<G4ManyFastLists_iterator<typename ObjectW::type> > ManyListsIteratorW; 133 using ManyListsIteratorW = type_wrapper<G4ManyFastLists_iterator<OBJECT>>; 134 135 //#ifdef WIN32 136 // friend typename ListW::type; 137 // friend typename ManyListsW::type; 138 // friend typename ManyListsIteratorW::type; 139 ////#elif defined(__clang__) 140 //// friend T; 141 //// friend G4ManyFastLists_iterator<OBJECT>; 142 //#else 143 // friend class ListW::type; 144 // friend class ManyListsW::type; 145 // friend struct ManyListsIteratorW::type; 146 //#endif 147 148 public: 149 ~G4FastListNode(); 150 151 OBJECT* GetObject() 152 { 153 return fpObject; 154 } 155 156 const OBJECT* GetObject() const 157 { 158 return fpObject; 159 } 160 161 G4FastListNode<OBJECT>* GetNext() 162 { 163 return fpNext; 164 } 165 const G4FastListNode<OBJECT>* GetNext() const 166 { 167 return fpNext; 168 } 169 G4FastListNode<OBJECT>* GetPrevious() 170 { 171 return fpPrevious; 172 } 173 const G4FastListNode<OBJECT>* GetPrevious() const 174 { 175 return fpPrevious; 176 } 177 bool IsAttached() 178 { 179 return fAttachedToList; 180 } 181 182 //protected: 183 /** Default constructor */ 184 G4FastListNode(OBJECT* track = nullptr); 185 186 void SetNext(G4FastListNode<OBJECT>* node) 187 { 188 fpNext = node; 189 } 190 void SetPrevious(G4FastListNode<OBJECT>* node) 191 { 192 fpPrevious = node; 193 } 194 void SetAttachedToList(bool flag) 195 { 196 fAttachedToList = flag; 197 } 198 199 void UnHook(); 200 201 void DetachYourSelf(); 202 203 bool fAttachedToList; 204 G4shared_ptr<_ListRef<G4FastList<OBJECT> > > fListRef; 205 OBJECT* fpObject; 206 G4FastListNode<OBJECT>* fpPrevious; 207 G4FastListNode<OBJECT>* fpNext; 208 }; 209 210 /** 211 * G4FastList is used by G4TrackHolder to save 212 * G4IT tracks only. Its advantage lies to a fast 213 * search of a track in this list. 214 */ 215 216 template<class OBJECT> 217 class G4FastList 218 { 219 protected: 220 G4int fNbObjects; 221 // G4FastListNode<OBJECT> * fpStart; 222 // G4FastListNode<OBJECT> * fpFinish; 223 G4shared_ptr<_ListRef<G4FastList<OBJECT> > > fListRef; 224 225 G4FastListNode<OBJECT> fBoundary; 226 // Must be empty and link to the last non-empty node of the list 227 // and to the first non-empty node of the list (begin()) 228 // The iterator returned by end() is linked to this empty node 229 230 public: 231 class Watcher 232 { 233 public: 234 enum Priority 235 { 236 eExtreme, 237 eHigh, 238 eNormal, 239 eLow, 240 eVeryLow 241 }; 242 243 using list = G4FastList<OBJECT>; 244 245 Watcher() 246 { 247 fPriority = Priority::eVeryLow; 248 } 249 250 virtual ~Watcher() 251 { 252 auto it = fWatching.begin(); 253 auto end = fWatching.end(); 254 for(;it!=end;it++) 255 { 256 (*it)->RemoveWatcher(this); 257 } 258 } 259 260 virtual G4String GetWatcherName(){ 261 return ""; 262 } 263 264 Priority GetPriority() const{ 265 return fPriority; 266 } 267 268 // =============================== 269 // NOTIFICATIONS 270 void NotifyDeletingList(G4FastList<OBJECT>*){;} 271 // used by PriorityList & ManyFastLists 272 273 virtual void NotifyAddObject(OBJECT*, G4FastList<OBJECT>*){;} 274 virtual void NotifyRemoveObject(OBJECT*, G4FastList<OBJECT>*){;} 275 // void NotifyEmpty(OBJECT*, G4FastList<OBJECT>*){;} 276 277 // =============================== 278 279 void Watch(G4FastList<OBJECT>* fastList) 280 { 281 fWatching.insert(fastList); 282 fastList->AddWatcher(this); 283 } 284 285 void StopWatching(G4FastList<OBJECT>* fastList, bool removeWatcher = true) 286 { 287 auto it = fWatching.find(fastList); 288 if(it == fWatching.end()) return; //TODO: exception? 289 fWatching.erase(it); 290 if(removeWatcher) fastList->RemoveWatcher(this); 291 } 292 293 protected: 294 Priority fPriority; 295 296 private: 297 std::set<G4FastList<OBJECT>*> fWatching; 298 }; 299 300 template<typename WATCHER_TYPE> 301 class TWatcher : public Watcher 302 { 303 public: 304 TWatcher() : Watcher(){} 305 virtual ~TWatcher()= default; 306 virtual G4String GetWatcherName() 307 { 308 return typeid(WATCHER_TYPE).name(); 309 } 310 }; 311 312 protected: 313 using WatcherSet = std::set<typename G4FastList<OBJECT>::Watcher*, 314 sortWatcher<OBJECT>>; 315 WatcherSet fWatchers; 316 G4FastListNode<G4FastList<OBJECT> >* fpNodeInManyLists; 317 318 public: 319 using object = OBJECT; 320 using iterator = G4FastList_iterator<OBJECT>; 321 using const_iterator = G4FastList_const_iterator<OBJECT>; 322 using node = G4FastListNode<OBJECT>; 323 324 G4FastList(); 325 ~G4FastList(); 326 327 void SetListNode(G4FastListNode<G4FastList<OBJECT> >* __node) 328 { 329 fpNodeInManyLists = __node; 330 } 331 332 G4FastListNode<G4FastList<OBJECT> >* GetListNode() 333 { 334 return fpNodeInManyLists; 335 } 336 337 void AddWatcher(Watcher* watcher) 338 { 339 fWatchers.insert(watcher); 340 } 341 342 void RemoveWatcher(Watcher* watcher) 343 { 344 auto it = fWatchers.find(watcher); 345 if(it == fWatchers.end()) return; //TODO: exception? 346 fWatchers.erase(it); 347 } 348 349 inline OBJECT* back() 350 { 351 // if (fNbObjects != 0) return fpFinish->GetObject(); 352 if (fNbObjects != 0) return fBoundary.GetPrevious()->GetObject(); 353 return 0; 354 } 355 356 inline G4int size() const 357 { 358 return fNbObjects; 359 } 360 361 inline bool empty() const; 362 iterator insert(iterator /*position*/, OBJECT*); 363 364 inline iterator begin(); 365 inline const_iterator begin() const; 366 367 inline iterator end(); 368 inline const_iterator end() const; 369 /** 370 * return an iterator that contains an empty node 371 * use for boundary checking only 372 */ 373 374 bool Holds(const OBJECT*) const; 375 376 inline void push_front(OBJECT* __track); 377 inline void push_back(OBJECT* __track); 378 OBJECT* pop_back(); 379 380 void remove(OBJECT*); 381 382 iterator pop(OBJECT*); 383 iterator pop(G4FastListNode<OBJECT>*); 384 iterator pop(iterator __first, iterator __last); 385 iterator erase(OBJECT*); 386 /** 387 * Complexity = constant 388 * By storing the node inside the object, we avoid 389 * searching through all the container. 390 */ 391 392 iterator erase(iterator __first, iterator __last); 393 /** 394 * Complexity = linear in size between __first and __last 395 */ 396 397 void clear(); 398 void transferTo(G4FastList<OBJECT>*); 399 /** 400 * Complexity = constant 401 */ 402 403 static G4FastListNode<OBJECT>* GetNode(OBJECT*); 404 static void SetNode(OBJECT* __obj, G4FastListNode<OBJECT>* __node); 405 static G4FastList<OBJECT>* GetList(OBJECT*); 406 static G4FastList<OBJECT>* GetList(G4FastListNode<OBJECT>* __trackListNode); 407 static void Pop(OBJECT*); 408 409 protected: 410 G4FastListNode<OBJECT>* CreateNode(OBJECT*); 411 static G4FastListNode<OBJECT>* __GetNode(OBJECT*); 412 G4FastListNode<OBJECT>* Flag(OBJECT*); 413 G4FastListNode<OBJECT>* Unflag(OBJECT*); 414 void Unflag(G4FastListNode<OBJECT>* __trackListNode); 415 void CheckFlag(G4FastListNode<OBJECT>*); 416 void DeleteObject(OBJECT*); 417 418 void Hook(G4FastListNode<OBJECT>* /*position*/, 419 G4FastListNode<OBJECT>* /*toHook*/); 420 void Unhook(G4FastListNode<OBJECT>*); 421 G4FastListNode<OBJECT>* EraseListNode(OBJECT*); 422 423 private: 424 G4FastList(const G4FastList<OBJECT>& other); 425 G4FastList<OBJECT> & operator=(const G4FastList<OBJECT> &right); 426 G4bool operator==(const G4FastList<OBJECT> &right) const; 427 G4bool operator!=(const G4FastList<OBJECT> &right) const; 428 }; 429 430 431 template<class OBJECT> 432 struct sortWatcher 433 { 434 bool operator()(const typename G4FastList<OBJECT>::Watcher* left, 435 const typename G4FastList<OBJECT>::Watcher* right) const 436 { 437 if(left && right) 438 { 439 if(left->GetPriority() != right->GetPriority()) 440 { 441 return left->GetPriority() < right->GetPriority(); 442 } 443 return left < right; 444 } 445 return false; 446 } 447 }; 448 449 450 /** 451 * G4FastList_iterator enables to go through 452 * the tracks contained by a list. 453 */ 454 455 template<typename OBJECT> 456 struct G4FastList_iterator 457 { 458 // friend class G4FastList<OBJECT>; 459 using _Self = G4FastList_iterator<OBJECT>; 460 using _Node = G4FastListNode<OBJECT>; 461 462 G4FastList_iterator() = default; 463 464 explicit G4FastList_iterator(_Node* __x) : 465 fpNode(__x) 466 { 467 } 468 469 G4FastList_iterator(const G4FastList_iterator& right) = default; 470 _Self& operator=(const G4FastList_iterator& right) = default; 471 472 _Node* GetNode() 473 { 474 return fpNode; 475 } 476 477 const _Node* GetNode() const 478 { 479 return fpNode; 480 } 481 482 OBJECT* 483 operator*(); 484 485 const OBJECT* 486 operator*() const; 487 488 OBJECT* 489 operator->(); 490 491 const OBJECT* 492 operator->() const; 493 494 _Self& 495 operator++() 496 { 497 fpNode = fpNode->GetNext(); 498 return *this; 499 } 500 501 _Self operator++(int) 502 { 503 _Self __tmp = *this; 504 fpNode = fpNode->GetNext(); 505 return __tmp; 506 } 507 508 _Self& 509 operator--() 510 { 511 fpNode = fpNode->GetPrevious(); 512 return *this; 513 } 514 515 _Self operator--(int) 516 { 517 _Self __tmp = *this; 518 fpNode = fpNode->GetPrevious(); 519 return __tmp; 520 } 521 522 G4bool operator==(const _Self& __x) const 523 { 524 return (fpNode == __x.fpNode); 525 } 526 527 G4bool operator!=(const _Self& __x) const 528 { 529 return (fpNode != __x.fpNode); 530 } 531 532 // private: 533 // The only member points to the G4FastList_iterator element. 534 _Node* fpNode = nullptr; 535 }; 536 537 /** 538 * G4FastList_iterator enables to go through 539 * the tracks contained by a list. 540 */ 541 542 template<typename OBJECT> 543 struct G4FastList_const_iterator 544 { 545 // friend class G4FastList<OBJECT>; 546 using _Self = G4FastList_const_iterator<OBJECT>; 547 using _Node = G4FastListNode<OBJECT>; 548 549 G4FastList_const_iterator() = default; 550 551 explicit G4FastList_const_iterator(const _Node* __x) : 552 fpNode(__x) 553 { 554 } 555 556 G4FastList_const_iterator(const G4FastList_const_iterator& right) = default; 557 _Self& operator=(const G4FastList_const_iterator& right) = default; 558 559 G4FastList_const_iterator(const G4FastList_iterator<OBJECT>& right) : 560 fpNode(right.GetNode()) 561 { 562 } 563 564 _Self& operator=(const G4FastList_iterator<OBJECT>& right) 565 { 566 fpNode = right.GetNode(); 567 return *this; 568 } 569 570 const OBJECT* 571 operator*() const 572 { 573 if(fpNode == nullptr) return nullptr; 574 return fpNode->GetObject(); 575 } 576 577 const OBJECT* 578 operator->() const 579 { 580 if(fpNode == 0) return 0; 581 return fpNode->GetObject(); 582 } 583 584 _Self& 585 operator++() 586 { 587 fpNode = fpNode->GetNext(); 588 return *this; 589 } 590 591 _Self operator++(int) 592 { 593 _Self __tmp = *this; 594 fpNode = fpNode->GetNext(); 595 return __tmp; 596 } 597 598 _Self& 599 operator--() 600 { 601 fpNode = fpNode->GetPrevious(); 602 return *this; 603 } 604 605 _Self operator--(int) 606 { 607 _Self __tmp = *this; 608 fpNode = fpNode->GetPrevious(); 609 return __tmp; 610 } 611 612 G4bool operator==(const _Self& __x) const 613 { 614 return (fpNode == __x.fpNode); 615 } 616 617 G4bool operator!=(const _Self& __x) const 618 { 619 return (fpNode != __x.fpNode); 620 } 621 622 // private: 623 // The only member points to the G4FastList_iterator element. 624 const _Node* fpNode = nullptr; 625 }; 626 627 #include "G4FastList.icc" 628