Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:58:16

0001 //
0002 // ********************************************************************
0003 // * License and Disclaimer                                           *
0004 // *                                                                  *
0005 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
0006 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
0007 // * conditions of the Geant4 Software License,  included in the file *
0008 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
0009 // * include a list of copyright holders.                             *
0010 // *                                                                  *
0011 // * Neither the authors of this software system, nor their employing *
0012 // * institutes,nor the agencies providing financial support for this *
0013 // * work  make  any representation or  warranty, express or implied, *
0014 // * regarding  this  software system or assume any liability for its *
0015 // * use.  Please see the license in the file  LICENSE  and URL above *
0016 // * for the full disclaimer and the limitation of liability.         *
0017 // *                                                                  *
0018 // * This  code  implementation is the result of  the  scientific and *
0019 // * technical work of the GEANT4 collaboration.                      *
0020 // * By using,  copying,  modifying or  distributing the software (or *
0021 // * any work based  on the software)  you  agree  to acknowledge its *
0022 // * use  in  resulting  scientific  publications,  and indicate your *
0023 // * acceptance of all terms of the Geant4 Software license.          *
0024 // ********************************************************************
0025 //
0026 //
0027 // Author: Mathieu Karamitros
0028 
0029 // The code is developed in the framework of the ESA AO7146
0030 //
0031 // We would be very happy hearing from you, send us your feedback! :)
0032 //
0033 // In order for Geant4-DNA to be maintained and still open-source,
0034 // article citations are crucial. 
0035 // If you use Geant4-DNA chemistry and you publish papers about your software, 
0036 // in addition to the general paper on Geant4-DNA:
0037 //
0038 // Int. J. Model. Simul. Sci. Comput. 1 (2010) 157–178
0039 //
0040 // we would be very happy if you could please also cite the following
0041 // reference papers on chemistry:
0042 //
0043 // J. Comput. Phys. 274 (2014) 841-882
0044 // Prog. Nucl. Sci. Tec. 2 (2011) 503-508 
0045 
0046 #pragma once
0047 
0048 #include "globals.hh"
0049 #include "G4ReferenceCountedHandle.hh"
0050 #include <G4memory.hh>
0051 #include <vector>
0052 #include <set>
0053 //#include "G4ManyFastLists.hh"
0054 
0055 template<class OBJECT>
0056   class G4FastList;
0057 template<class OBJECT>
0058   class G4FastList_Boundary;
0059 template<typename OBJECT>
0060   struct G4FastList_iterator;
0061 template<typename OBJECT>
0062   struct G4FastList_const_iterator;
0063 template<typename OBJECT>
0064   class G4ManyFastLists;
0065 template<typename OBJECT>
0066   struct G4ManyFastLists_iterator;
0067 template<class OBJECT>
0068   struct sortWatcher;
0069 
0070 
0071 /** Comments :
0072  * - A track cannot belong to two different track lists
0073  * - Erase a given track is constant complexity
0074  * - This development was thought to be used together with G4IT
0075  */
0076 
0077 #ifndef TYPE_WRAPPER
0078 #define TYPE_WRAPPER
0079 template < typename T>
0080 struct type_wrapper
0081 {
0082    using type = T;
0083 };
0084 #endif
0085 
0086 template<class LIST>
0087   struct _ListRef
0088   {
0089     using traits_type = type_wrapper<LIST>;
0090     using mli_traits_type = type_wrapper<G4ManyFastLists_iterator<typename LIST::object>>;
0091 
0092 //#ifdef WIN32
0093 //    friend typename traits_type::type;
0094 //    friend typename traits_type::type::node;
0095 //    friend typename mli_traits_type::type;
0096 ////#elif defined(__clang__)
0097 ////    friend T;
0098 ////    friend T::node;
0099 ////    friend G4ManyFastLists_iterator<traits_type::type::object>;
0100 //#else
0101 //    friend class traits_type::type;
0102 //    friend class traits_type::type::node;
0103 //    friend class mli_traits_type::type;
0104 //#endif
0105 
0106     LIST* fpList;
0107 
0108 //  protected:
0109     inline _ListRef(LIST* __list) :
0110         fpList(__list)
0111     {
0112       ;
0113     }
0114  };
0115 
0116 /**
0117  * G4FastListNode is the entity actually stored
0118  * by the G4FastList. A G4FastListNode should
0119  * belong only to one list. Also, an object
0120  * should belong only to one list.
0121  */
0122 
0123 template<class OBJECT>
0124   class G4FastListNode
0125   {
0126     using ObjectW = type_wrapper<OBJECT>;
0127     using LIST = G4FastList<typename ObjectW::type>;
0128 //    typedef type_wrapper<LIST> > ListW;
0129     using ListW = type_wrapper<G4FastList<OBJECT>>;
0130 //    typedef type_wrapper<G4ManyFastLists<typename ObjectW::type> > ManyListsW;
0131     using ManyListsW = type_wrapper<G4ManyFastLists<OBJECT>>;
0132 //    typedef type_wrapper<G4ManyFastLists_iterator<typename ObjectW::type> > ManyListsIteratorW;
0133     using ManyListsIteratorW = type_wrapper<G4ManyFastLists_iterator<OBJECT>>;
0134 
0135 //#ifdef WIN32
0136 //    friend typename ListW::type;
0137 //    friend typename ManyListsW::type;
0138 //    friend typename ManyListsIteratorW::type;
0139 ////#elif defined(__clang__)
0140 ////    friend T;
0141 ////    friend G4ManyFastLists_iterator<OBJECT>;
0142 //#else
0143 //    friend class ListW::type;
0144 //    friend class ManyListsW::type;
0145 //    friend struct ManyListsIteratorW::type;
0146 //#endif
0147 
0148   public:
0149     ~G4FastListNode();
0150 
0151     OBJECT* GetObject()
0152     {
0153       return fpObject;
0154     }
0155 
0156     const OBJECT* GetObject() const
0157     {
0158       return fpObject;
0159     }
0160 
0161     G4FastListNode<OBJECT>* GetNext()
0162     {
0163       return fpNext;
0164     }
0165     const G4FastListNode<OBJECT>* GetNext() const
0166     {
0167       return fpNext;
0168     }
0169     G4FastListNode<OBJECT>* GetPrevious()
0170     {
0171       return fpPrevious;
0172     }
0173     const G4FastListNode<OBJECT>* GetPrevious() const
0174     {
0175       return fpPrevious;
0176     }
0177     bool IsAttached()
0178     {
0179       return fAttachedToList;
0180     }
0181 
0182   //protected:
0183     /** Default constructor */
0184     G4FastListNode(OBJECT* track = nullptr);
0185 
0186     void SetNext(G4FastListNode<OBJECT>* node)
0187     {
0188       fpNext = node;
0189     }
0190     void SetPrevious(G4FastListNode<OBJECT>* node)
0191     {
0192       fpPrevious = node;
0193     }
0194     void SetAttachedToList(bool flag)
0195     {
0196       fAttachedToList = flag;
0197     }
0198 
0199     void UnHook();
0200 
0201     void DetachYourSelf();
0202     
0203     bool fAttachedToList;
0204     G4shared_ptr<_ListRef<G4FastList<OBJECT> > > fListRef;
0205     OBJECT* fpObject;
0206     G4FastListNode<OBJECT>* fpPrevious;
0207     G4FastListNode<OBJECT>* fpNext;
0208   };
0209 
0210 /**
0211  * G4FastList is used by G4TrackHolder to save
0212  * G4IT tracks only. Its advantage lies to a fast
0213  * search of a track in this list.
0214  */
0215 
0216 template<class OBJECT>
0217   class G4FastList
0218   {
0219   protected:
0220     G4int fNbObjects;
0221 //    G4FastListNode<OBJECT> * fpStart;
0222 //    G4FastListNode<OBJECT> * fpFinish;
0223     G4shared_ptr<_ListRef<G4FastList<OBJECT> > > fListRef;
0224 
0225     G4FastListNode<OBJECT> fBoundary;
0226     // Must be empty and link to the last non-empty node of the list
0227     // and to the first non-empty node of the list (begin())
0228     // The iterator returned by end() is linked to this empty node
0229 
0230   public:
0231     class Watcher
0232     {
0233     public:
0234       enum Priority
0235       {
0236         eExtreme,
0237         eHigh,
0238         eNormal,
0239         eLow,
0240         eVeryLow
0241       };
0242 
0243       using list = G4FastList<OBJECT>;
0244 
0245       Watcher()
0246       {
0247         fPriority = Priority::eVeryLow;
0248       }
0249 
0250       virtual ~Watcher()
0251       {
0252         auto it = fWatching.begin();
0253         auto end = fWatching.end();
0254         for(;it!=end;it++)
0255         {
0256           (*it)->RemoveWatcher(this);
0257         }
0258       }
0259 
0260       virtual G4String GetWatcherName(){
0261         return "";
0262       }
0263 
0264       Priority GetPriority() const{
0265         return fPriority;
0266       }
0267 
0268       // ===============================
0269       // NOTIFICATIONS
0270       void NotifyDeletingList(G4FastList<OBJECT>*){;}
0271       // used by PriorityList & ManyFastLists
0272 
0273       virtual void NotifyAddObject(OBJECT*, G4FastList<OBJECT>*){;}
0274       virtual void NotifyRemoveObject(OBJECT*, G4FastList<OBJECT>*){;}
0275 //      void NotifyEmpty(OBJECT*, G4FastList<OBJECT>*){;}
0276 
0277       // ===============================
0278 
0279       void Watch(G4FastList<OBJECT>* fastList)
0280       {
0281         fWatching.insert(fastList);
0282         fastList->AddWatcher(this);
0283       }
0284 
0285       void StopWatching(G4FastList<OBJECT>* fastList, bool removeWatcher = true)
0286       {
0287         auto it = fWatching.find(fastList);
0288         if(it == fWatching.end()) return; //TODO: exception?
0289         fWatching.erase(it);
0290         if(removeWatcher) fastList->RemoveWatcher(this);
0291       }
0292 
0293     protected:
0294       Priority fPriority;
0295 
0296     private:
0297       std::set<G4FastList<OBJECT>*> fWatching;
0298     };
0299 
0300     template<typename WATCHER_TYPE>
0301     class TWatcher : public Watcher
0302     {
0303       public:
0304       TWatcher() : Watcher(){}
0305       virtual ~TWatcher()= default;
0306       virtual G4String GetWatcherName()
0307       {
0308         return typeid(WATCHER_TYPE).name();
0309       }
0310     };
0311 
0312   protected:
0313     using WatcherSet = std::set<typename G4FastList<OBJECT>::Watcher*,
0314                     sortWatcher<OBJECT>>;
0315     WatcherSet   fWatchers;
0316     G4FastListNode<G4FastList<OBJECT> >* fpNodeInManyLists;
0317 
0318   public:
0319     using object = OBJECT;
0320     using iterator = G4FastList_iterator<OBJECT>;
0321     using const_iterator = G4FastList_const_iterator<OBJECT>;
0322     using node = G4FastListNode<OBJECT>;
0323 
0324     G4FastList();
0325     ~G4FastList();
0326 
0327     void SetListNode(G4FastListNode<G4FastList<OBJECT> >* __node)
0328     {
0329       fpNodeInManyLists = __node;
0330     }
0331 
0332     G4FastListNode<G4FastList<OBJECT> >* GetListNode()
0333     {
0334       return fpNodeInManyLists;
0335     }
0336 
0337     void AddWatcher(Watcher* watcher)
0338     {
0339       fWatchers.insert(watcher);
0340     }
0341 
0342     void RemoveWatcher(Watcher* watcher)
0343     {
0344       auto it = fWatchers.find(watcher);
0345       if(it == fWatchers.end()) return; //TODO: exception?
0346       fWatchers.erase(it);
0347     }
0348 
0349     inline OBJECT* back()
0350     {
0351 //      if (fNbObjects != 0) return fpFinish->GetObject();
0352       if (fNbObjects != 0) return fBoundary.GetPrevious()->GetObject();
0353       return 0;
0354     }
0355 
0356     inline G4int size() const
0357     {
0358       return fNbObjects;
0359     }
0360 
0361     inline bool empty() const;
0362     iterator insert(iterator /*position*/, OBJECT*);
0363 
0364     inline iterator begin();
0365     inline const_iterator begin() const;
0366 
0367     inline iterator end();
0368     inline const_iterator end() const;
0369     /**
0370      * return an iterator that contains an empty node
0371      * use for boundary checking only
0372      */
0373 
0374     bool Holds(const OBJECT*) const;
0375 
0376     inline void push_front(OBJECT* __track);
0377     inline void push_back(OBJECT* __track);
0378     OBJECT* pop_back();
0379 
0380     void remove(OBJECT*);
0381 
0382     iterator pop(OBJECT*);
0383     iterator pop(G4FastListNode<OBJECT>*);
0384     iterator pop(iterator __first, iterator __last);
0385     iterator erase(OBJECT*);
0386     /**
0387      * Complexity = constant
0388      * By storing the node inside the object, we avoid
0389      * searching through all the container.
0390      */
0391 
0392     iterator erase(iterator __first, iterator __last);
0393     /**
0394      * Complexity = linear in size between __first and __last
0395      */
0396 
0397     void clear();
0398     void transferTo(G4FastList<OBJECT>*);
0399     /**
0400      * Complexity = constant
0401      */
0402 
0403     static G4FastListNode<OBJECT>* GetNode(OBJECT*);
0404     static void SetNode(OBJECT* __obj, G4FastListNode<OBJECT>* __node);
0405     static G4FastList<OBJECT>* GetList(OBJECT*);
0406     static G4FastList<OBJECT>* GetList(G4FastListNode<OBJECT>* __trackListNode);
0407     static void Pop(OBJECT*);
0408 
0409   protected:
0410     G4FastListNode<OBJECT>* CreateNode(OBJECT*);
0411     static G4FastListNode<OBJECT>* __GetNode(OBJECT*);
0412     G4FastListNode<OBJECT>* Flag(OBJECT*);
0413     G4FastListNode<OBJECT>* Unflag(OBJECT*);
0414     void Unflag(G4FastListNode<OBJECT>* __trackListNode);
0415     void CheckFlag(G4FastListNode<OBJECT>*);
0416     void DeleteObject(OBJECT*);
0417 
0418     void Hook(G4FastListNode<OBJECT>* /*position*/,
0419               G4FastListNode<OBJECT>* /*toHook*/);
0420     void Unhook(G4FastListNode<OBJECT>*);
0421     G4FastListNode<OBJECT>* EraseListNode(OBJECT*);
0422 
0423   private:
0424     G4FastList(const G4FastList<OBJECT>& other);
0425     G4FastList<OBJECT> & operator=(const G4FastList<OBJECT> &right);
0426     G4bool operator==(const G4FastList<OBJECT> &right) const;
0427     G4bool operator!=(const G4FastList<OBJECT> &right) const;
0428   };
0429 
0430 
0431 template<class OBJECT>
0432   struct sortWatcher
0433   {
0434     bool operator()(const typename G4FastList<OBJECT>::Watcher* left,
0435                     const typename G4FastList<OBJECT>::Watcher* right) const
0436     {
0437       if(left && right)
0438       {
0439         if(left->GetPriority() != right->GetPriority())
0440         {
0441           return left->GetPriority() < right->GetPriority();
0442         }
0443         return left < right;
0444       }
0445       return false;
0446     }
0447   };
0448 
0449 
0450 /**
0451  * G4FastList_iterator enables to go through
0452  * the tracks contained by a list.
0453  */
0454 
0455 template<typename OBJECT>
0456   struct G4FastList_iterator
0457   {
0458 //    friend class G4FastList<OBJECT>;
0459     using _Self = G4FastList_iterator<OBJECT>;
0460     using _Node = G4FastListNode<OBJECT>;
0461 
0462     G4FastList_iterator() = default;
0463 
0464     explicit G4FastList_iterator(_Node* __x) :
0465         fpNode(__x)
0466     {
0467     }
0468 
0469     G4FastList_iterator(const G4FastList_iterator& right) = default;
0470     _Self& operator=(const G4FastList_iterator& right) = default;
0471 
0472     _Node* GetNode()
0473     {
0474       return fpNode;
0475     }
0476 
0477     const _Node* GetNode() const
0478     {
0479       return fpNode;
0480     }
0481 
0482     OBJECT*
0483     operator*();
0484 
0485     const OBJECT*
0486     operator*() const;
0487 
0488     OBJECT*
0489     operator->();
0490 
0491     const OBJECT*
0492     operator->() const;
0493 
0494     _Self&
0495     operator++()
0496     {
0497       fpNode = fpNode->GetNext();
0498       return *this;
0499     }
0500 
0501     _Self operator++(int)
0502     {
0503       _Self __tmp = *this;
0504       fpNode = fpNode->GetNext();
0505       return __tmp;
0506     }
0507 
0508     _Self&
0509     operator--()
0510     {
0511       fpNode = fpNode->GetPrevious();
0512       return *this;
0513     }
0514 
0515     _Self operator--(int)
0516     {
0517       _Self __tmp = *this;
0518       fpNode = fpNode->GetPrevious();
0519       return __tmp;
0520     }
0521 
0522     G4bool operator==(const _Self& __x) const
0523     {
0524       return (fpNode == __x.fpNode);
0525     }
0526 
0527     G4bool operator!=(const _Self& __x) const
0528     {
0529       return (fpNode != __x.fpNode);
0530     }
0531 
0532 //  private:
0533     // The only member points to the G4FastList_iterator element.
0534     _Node* fpNode = nullptr;
0535   };
0536 
0537 /**
0538  * G4FastList_iterator enables to go through
0539  * the tracks contained by a list.
0540  */
0541 
0542 template<typename OBJECT>
0543   struct G4FastList_const_iterator
0544   {
0545 //    friend class G4FastList<OBJECT>;
0546     using _Self = G4FastList_const_iterator<OBJECT>;
0547     using _Node = G4FastListNode<OBJECT>;
0548 
0549     G4FastList_const_iterator() = default;
0550 
0551     explicit G4FastList_const_iterator(const _Node* __x) :
0552         fpNode(__x)
0553     {
0554     }
0555 
0556     G4FastList_const_iterator(const G4FastList_const_iterator& right) = default;
0557     _Self& operator=(const G4FastList_const_iterator& right) = default;
0558 
0559     G4FastList_const_iterator(const G4FastList_iterator<OBJECT>& right) :
0560         fpNode(right.GetNode())
0561     {
0562     }
0563 
0564     _Self& operator=(const G4FastList_iterator<OBJECT>& right)
0565     {
0566       fpNode = right.GetNode();
0567       return *this;
0568     }
0569 
0570     const OBJECT*
0571     operator*() const
0572     {
0573       if(fpNode == nullptr) return nullptr;
0574       return fpNode->GetObject();
0575     }
0576 
0577     const OBJECT*
0578     operator->() const
0579     {
0580       if(fpNode == 0) return 0;
0581       return fpNode->GetObject();
0582     }
0583 
0584     _Self&
0585     operator++()
0586     {
0587       fpNode = fpNode->GetNext();
0588       return *this;
0589     }
0590 
0591     _Self operator++(int)
0592     {
0593       _Self __tmp = *this;
0594       fpNode = fpNode->GetNext();
0595       return __tmp;
0596     }
0597 
0598     _Self&
0599     operator--()
0600     {
0601       fpNode = fpNode->GetPrevious();
0602       return *this;
0603     }
0604 
0605     _Self operator--(int)
0606     {
0607       _Self __tmp = *this;
0608       fpNode = fpNode->GetPrevious();
0609       return __tmp;
0610     }
0611 
0612     G4bool operator==(const _Self& __x) const
0613     {
0614       return (fpNode == __x.fpNode);
0615     }
0616 
0617     G4bool operator!=(const _Self& __x) const
0618     {
0619       return (fpNode != __x.fpNode);
0620     }
0621 
0622 //  private:
0623     // The only member points to the G4FastList_iterator element.
0624     const _Node* fpNode = nullptr;
0625   };
0626 
0627 #include "G4FastList.icc"