Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/processes/electromagnetic/dna/management/include/G4FastList.hh

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

  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