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 (kara (AT) cenbg . in2p3 . fr)
0028 //
0029 // History:
0030 // -----------
0031 // 10 Oct 2011 M.Karamitros created
0032 //
0033 // -------------------------------------------------------------------
0034 
0035 //#ifndef G4FASTLIST_ICC_
0036 //#define G4FASTLIST_ICC_
0037 
0038 //***********************************************************
0039 // TrackList_iterator
0040 template<class OBJECT>
0041   OBJECT*
0042   G4FastList_iterator<OBJECT>::operator*()
0043   {
0044     if (fpNode == nullptr) return nullptr;
0045     return fpNode->GetObject();
0046   }
0047 
0048 template<class OBJECT>
0049   OBJECT*
0050   G4FastList_iterator<OBJECT>::operator->()
0051   {
0052     if (fpNode == nullptr) return nullptr;
0053     return fpNode->GetObject();
0054   }
0055 
0056 template<class OBJECT>
0057   const OBJECT*
0058   G4FastList_iterator<OBJECT>::operator*() const
0059   {
0060     if (fpNode == 0) return 0;
0061     return fpNode->GetObject();
0062   }
0063 
0064 template<class OBJECT>
0065   const OBJECT*
0066   G4FastList_iterator<OBJECT>::operator->() const
0067   {
0068     if (fpNode == 0) return 0;
0069     return fpNode->GetObject();
0070   }
0071 
0072 //***********************************************************
0073 // TrackNodeList
0074 
0075 template<class OBJECT>
0076   G4FastListNode<OBJECT>::G4FastListNode(OBJECT* track) :
0077       fpObject(track), fpPrevious(nullptr), fpNext(nullptr)
0078   {
0079     fAttachedToList = false;
0080   }
0081 
0082 template<class OBJECT>
0083   G4FastListNode<OBJECT>::~G4FastListNode()
0084   {
0085     if (fListRef && fListRef->fpList)
0086     {
0087       fListRef->fpList->pop(this);
0088     }
0089   }
0090 
0091 template<class OBJECT>
0092   void G4FastListNode<OBJECT>::DetachYourSelf()
0093   {
0094     if(fpObject)
0095     {
0096       fpObject->SetListNode(nullptr);
0097     }
0098   }
0099 
0100 //***********************************************************
0101 
0102 template<class OBJECT>
0103   G4FastList<OBJECT>::G4FastList() :
0104       fBoundary()
0105   {
0106     fListRef.reset(new _ListRef<G4FastList<OBJECT> >(this));
0107     fNbObjects = 0;
0108     fBoundary.SetPrevious(&fBoundary);
0109     fBoundary.SetNext(&fBoundary);
0110     fBoundary.fAttachedToList = true;
0111     fpNodeInManyLists = nullptr;
0112   }
0113 
0114 // should not be used
0115 template<class OBJECT>
0116   G4FastList<OBJECT>::G4FastList(const G4FastList<OBJECT>& /*other*/) :
0117       fBoundary()
0118   {
0119     // One track should not belong to two different trackLists
0120     fNbObjects = 0;
0121     fpNodeInManyLists = 0;
0122   }
0123 
0124 template<class OBJECT>
0125   G4FastList<OBJECT>& G4FastList<OBJECT>::operator=(const G4FastList<OBJECT>& other)
0126   {
0127     // One track should not belong to two different trackList
0128     if (this == &other) return *this; // handle self assignment
0129     //assignment operator
0130     return *this;
0131   }
0132 
0133 template<class OBJECT>
0134   G4FastList<OBJECT>::~G4FastList()
0135   {
0136     if (fNbObjects != 0)
0137     {
0138       G4FastListNode<OBJECT> * __stackedTrack = fBoundary.GetNext();
0139       G4FastListNode<OBJECT> * __nextStackedTrack;
0140 
0141       // delete tracks in the stack
0142       while (__stackedTrack && __stackedTrack != &(fBoundary))
0143       {
0144         __nextStackedTrack = __stackedTrack->GetNext();
0145         OBJECT* __obj = __stackedTrack->GetObject();
0146 
0147         delete __stackedTrack;
0148         __stackedTrack = nullptr;
0149 
0150         if (__obj)
0151         {
0152           //////////////
0153           DeleteObject(__obj);
0154           __obj = nullptr;
0155           //////////////
0156         }
0157         __stackedTrack = __nextStackedTrack;
0158       }
0159     }
0160     fNbObjects = 0;
0161 
0162     auto it = fWatchers.begin();
0163     auto _end = fWatchers.end();
0164 
0165     for (; it != _end; it++)
0166     {
0167       (*it)->NotifyDeletingList(this);
0168       (*it)->StopWatching(this, false);
0169     }
0170 
0171     if (fpNodeInManyLists)
0172     {
0173       delete fpNodeInManyLists;
0174       fpNodeInManyLists = nullptr;
0175     }
0176   }
0177 
0178 template<class OBJECT>
0179   bool G4FastList<OBJECT>::empty() const
0180   {
0181     return (fNbObjects == 0);
0182   }
0183 
0184 template<class OBJECT>
0185   typename G4FastList<OBJECT>::iterator G4FastList<OBJECT>::begin()
0186   {
0187     return iterator(fBoundary.GetNext());
0188   }
0189 
0190 template<class OBJECT>
0191   typename G4FastList<OBJECT>::const_iterator G4FastList<OBJECT>::begin() const
0192   {
0193     return const_iterator(fBoundary.GetNext());
0194   }
0195 
0196 template<class OBJECT>
0197   typename G4FastList<OBJECT>::iterator G4FastList<OBJECT>::end()
0198   {
0199     return iterator(&(fBoundary));
0200   }
0201 
0202 template<class OBJECT>
0203   typename G4FastList<OBJECT>::const_iterator G4FastList<OBJECT>::end() const
0204   {
0205     return const_iterator(&(fBoundary));
0206   }
0207 // return an iterator that contains an empty node
0208 // use for boundary checking only
0209 
0210 template<class OBJECT>
0211   void G4FastList<OBJECT>::push_front(OBJECT* __obj)
0212   {
0213     insert(begin(), __obj);
0214   }
0215 
0216 template<class OBJECT>
0217   void G4FastList<OBJECT>::push_back(OBJECT* __obj)
0218   {
0219     insert(end(), __obj);
0220   }
0221 
0222 template<class OBJECT>
0223   bool G4FastList<OBJECT>::Holds(const OBJECT* __obj) const
0224   {
0225     node* __node = GetNode(__obj);
0226     if(__node == 0) return false;
0227     return (__node->fListRef->fpList == this);
0228   }
0229 
0230 // TODO: A revoir
0231 template<class OBJECT>
0232   G4FastListNode<OBJECT>* G4FastList<OBJECT>::Flag(OBJECT* __obj)
0233   {
0234     G4FastListNode<OBJECT>* __node = GetNode(__obj);
0235 
0236     if (__node != nullptr)
0237     {
0238       // Suggestion move the node to this list
0239       if (__node->fAttachedToList)
0240       {
0241         G4ExceptionDescription exceptionDescription;
0242         exceptionDescription << "An object";
0243         exceptionDescription << " is already attached to a TrackList ";
0244         G4Exception("G4FastList<OBJECT>::Flag", "G4FastList001",
0245                     FatalErrorInArgument, exceptionDescription);
0246       }
0247     }
0248     else
0249     {
0250       __node = new G4FastListNode<OBJECT>(__obj);
0251       SetNode(__obj,__node);
0252     }
0253 
0254     __node->fAttachedToList = true;
0255     __node->fListRef = fListRef;
0256     return __node;
0257   }
0258 
0259 template<class OBJECT>
0260   G4FastListNode<OBJECT>* G4FastList<OBJECT>::CreateNode(OBJECT* __obj)
0261   {
0262     G4FastListNode<OBJECT>* __listNode = Flag(__obj);
0263     return __listNode;
0264   }
0265 
0266 template<class OBJECT>
0267   void G4FastList<OBJECT>::Hook(G4FastListNode<OBJECT>* __position,
0268                                 G4FastListNode<OBJECT>* __toHook)
0269   {
0270     /*
0271      __toHook->SetNext(__position);
0272      __toHook->SetPrevious(__position->GetPrevious());
0273      __position->GetPrevious()->SetNext(__toHook);
0274      __position->SetPrevious(__toHook);
0275      */
0276     G4FastListNode<OBJECT>* __previous = __position->GetPrevious();
0277     __toHook->SetPrevious(__previous);
0278     __toHook->SetNext(__position);
0279     __position->SetPrevious(__toHook);
0280     __previous->SetNext(__toHook);
0281 
0282     /*
0283      if (fNbObjects == 0)
0284      {
0285      // DEBUG
0286      //        G4cout << "fNbObjects == 0" << G4endl;
0287      fpStart = __toHook;
0288      fpFinish = __toHook;
0289      __toHook->SetNext(&fBoundary);
0290      __toHook->SetPrevious(&fBoundary);
0291      //fBoundary.SetNext(__toHook);
0292      fBoundary.SetPrevious(__toHook);
0293      } else if (__position == &fBoundary)
0294      {
0295      // DEBUG
0296      //        G4cout << "__position == &fBoundary" << G4endl;
0297      fpFinish->SetNext(__toHook);
0298      __toHook->SetPrevious(fpFinish);
0299 
0300      __toHook->SetNext(&fBoundary);
0301      fBoundary.SetPrevious(__toHook);
0302 
0303      fpFinish = __toHook;
0304      } else if (__position == fpStart)
0305      {
0306      // DEBUG
0307      //        G4cout << "__position == fStart" << G4endl;
0308      __toHook->SetPrevious(&fBoundary);
0309      //fBoundary.SetNext(__toHook);
0310      __toHook->SetNext(fpStart);
0311      fpStart->SetPrevious(__toHook);
0312      fpStart = __toHook;
0313      } else
0314      {
0315      // DEBUG
0316      //        G4cout << "else" << G4endl;
0317      G4FastListNode<OBJECT>* __previous = __position->GetPrevious();
0318      __toHook->SetPrevious(__previous);
0319      __toHook->SetNext(__position);
0320      __position->SetPrevious(__toHook);
0321      __previous->SetNext(__toHook);
0322      }
0323      */
0324     fNbObjects++;
0325 
0326     if(fWatchers.empty() == false)
0327     {
0328       auto it = fWatchers.begin();
0329       auto _end = fWatchers.end();
0330 
0331       for (; it != _end; it++)
0332       {
0333         (*it)->NotifyAddObject(__toHook->GetObject(), this);
0334       }
0335     }
0336   }
0337 
0338 template<class OBJECT>
0339   void G4FastListNode<OBJECT>::UnHook()
0340   {
0341     G4FastListNode<OBJECT>* __next_node = this->fpNext;
0342     G4FastListNode<OBJECT>* __prev_node = this->fpPrevious;
0343 
0344     if (__prev_node)
0345     {
0346       __prev_node->fpNext = __next_node;
0347     }
0348 
0349     if (__next_node)
0350     {
0351       __next_node->fpPrevious = __prev_node;
0352     }
0353     fpNext = nullptr;
0354     fpPrevious = nullptr;
0355   }
0356 
0357 template<class OBJECT>
0358   void G4FastList<OBJECT>::Unhook(G4FastListNode<OBJECT>* __toUnHook)
0359   {
0360     __toUnHook->UnHook();
0361 
0362     fNbObjects--;
0363 
0364     auto it = fWatchers.begin();
0365     auto _end = fWatchers.end();
0366 
0367     for (; it != _end; it++)
0368     {
0369       (*it)->NotifyRemoveObject(__toUnHook->GetObject(), this);
0370     }
0371   }
0372 
0373 template<class OBJECT>
0374   typename G4FastList<OBJECT>::iterator
0375   G4FastList<OBJECT>::insert(typename G4FastList<OBJECT>::iterator __position,
0376                              OBJECT* __obj)
0377   {
0378     G4FastListNode<OBJECT>* __node = CreateNode(__obj);
0379     Hook(__position.fpNode, __node);
0380     return iterator(__node);
0381   }
0382 
0383 //____________________________________________________________________
0384 //
0385 //                      WITHDRAW FROM LIST
0386 //____________________________________________________________________
0387 
0388 template<class OBJECT>
0389   void G4FastList<OBJECT>::CheckFlag(G4FastListNode<OBJECT>* __node)
0390   {
0391     if (__node->fListRef->fpList != this)
0392     {
0393       G4ExceptionDescription exceptionDescription;
0394       exceptionDescription << "The object "
0395       << " is not correctly linked to a G4FastList." << G4endl
0396       << "You are probably trying to withdraw this object "
0397       << "from the list but it probably does not belong to "
0398       << "this fast list." << G4endl;
0399       G4Exception("G4FastList<OBJECT>::CheckFlag", "G4FastList002",
0400                   FatalErrorInArgument, exceptionDescription);
0401     }
0402   }
0403 
0404 template<class OBJECT>
0405   G4FastListNode<OBJECT>* G4FastList<OBJECT>::Unflag(OBJECT* __obj)
0406   {
0407     G4FastListNode<OBJECT>* __node = __GetNode(__obj);
0408     CheckFlag(__node);
0409     __node->fAttachedToList = false;
0410     __node->fListRef.reset();
0411     return __node;
0412   }
0413 
0414 template<class OBJECT>
0415   void G4FastList<OBJECT>::Unflag(G4FastListNode<OBJECT>* __node)
0416   {
0417     CheckFlag(__node);
0418     __node->fAttachedToList = false;
0419     __node->fListRef.reset();
0420     return;
0421   }
0422 
0423 template<class OBJECT>
0424   OBJECT* G4FastList<OBJECT>::pop_back()
0425   {
0426     if (fNbObjects == 0) return 0;
0427     G4FastListNode<OBJECT> * __aNode = fBoundary.GetPrevious();
0428     Unhook(__aNode);
0429     Unflag(__aNode);
0430     return __aNode->GetObject();
0431   }
0432 
0433 template<class OBJECT>
0434   typename G4FastList<OBJECT>::iterator G4FastList<OBJECT>::pop(OBJECT* __obj)
0435   {
0436     G4FastListNode<OBJECT>* __node = Unflag(__obj);
0437     iterator __next(__node->GetNext());
0438     Unhook(__node);
0439     return __next;
0440   }
0441 
0442 template<class OBJECT>
0443   typename G4FastList<OBJECT>::iterator
0444   G4FastList<OBJECT>::pop(G4FastListNode<OBJECT>* __node)
0445   {
0446     Unflag(__node);
0447     iterator __next(__node->GetNext());
0448     Unhook(__node);
0449     return __next;
0450   }
0451 
0452 template<class OBJECT>
0453   typename G4FastList<OBJECT>::iterator G4FastList<OBJECT>::erase(OBJECT* __obj)
0454   {
0455     G4FastListNode<OBJECT>* __next_node = EraseListNode(__obj);
0456     //////////////////
0457     DeleteObject(__obj);
0458     __obj = nullptr;
0459     //////////////////
0460     iterator __next(__next_node);
0461     return __next;
0462   }
0463 
0464 template<class OBJECT>
0465   G4FastListNode<OBJECT>* G4FastList<OBJECT>::EraseListNode(OBJECT* __obj)
0466   {
0467     G4FastListNode<OBJECT>* __node = Unflag(__obj);
0468     __node->DetachYourSelf();
0469     G4FastListNode<OBJECT>* __next = __node->GetNext();
0470     Unhook(__node);
0471     delete __node;
0472     return __next;
0473   }
0474 
0475 template<class OBJECT>
0476   void G4FastList<OBJECT>::DeleteObject(OBJECT*)
0477   {
0478 //    delete __obj;
0479   }
0480 
0481 template<class OBJECT>
0482   void G4FastList<OBJECT>::remove(OBJECT* __obj)
0483   {
0484     this->erase(__obj);
0485   }
0486 
0487 template<class OBJECT>
0488   typename G4FastList<OBJECT>::iterator G4FastList<OBJECT>::pop(iterator __first,
0489                                                                 iterator __last)
0490   {
0491     if (fNbObjects == 0) return iterator(&fBoundary);
0492 
0493     while (__first != __last)
0494     {
0495       if (__first.fpNode) __first = pop(*__first);
0496     }
0497     return __last;
0498   }
0499 
0500 template<class OBJECT>
0501   typename G4FastList<OBJECT>::iterator G4FastList<OBJECT>::erase(iterator __first,
0502                                                                   iterator __last)
0503   {
0504     if (fNbObjects == 0) return iterator(&fBoundary);
0505 
0506     while (__first != __last)
0507     {
0508       if (__first.fpNode) __first = erase(*__first);
0509     }
0510     return __last;
0511   }
0512 
0513 template<class OBJECT>
0514   void G4FastList<OBJECT>::clear()
0515   {
0516     erase(begin(), end());
0517   }
0518 
0519 template<class OBJECT>
0520   void G4FastList<OBJECT>::transferTo(G4FastList<OBJECT>* __destination)
0521   {
0522     if (fNbObjects == 0) return;
0523 
0524     if (__destination->fNbObjects == 0)
0525     {
0526 
0527       if(__destination->fWatchers.empty()==false)
0528       {
0529         auto it = __destination->fWatchers.begin();
0530         auto _end = __destination->fWatchers.end();
0531 
0532 //        G4cout << "G4FastList<OBJECT>::transferTo --- Watcher size = "
0533 //               << __destination->fWatchers.size()
0534 //               << G4endl;
0535 
0536         for (; it != _end; it++)
0537         {
0538           for(iterator it2 = this->begin() ;
0539               it2 != this->end(); ++it2
0540           )
0541           {
0542             (*it)->NotifyAddObject(*it2, this);
0543           }
0544         }
0545       }
0546 
0547       __destination->fNbObjects = this->fNbObjects;
0548 
0549       __destination->fBoundary.SetNext(fBoundary.GetNext());
0550       __destination->fBoundary.SetPrevious(fBoundary.GetPrevious());
0551       fBoundary.GetNext()->SetPrevious(&__destination->fBoundary);
0552       fBoundary.GetPrevious()->SetNext(&__destination->fBoundary);
0553     }
0554     else
0555     {
0556       if(__destination->fWatchers.empty()==false)
0557       {
0558         auto it = __destination->fWatchers.begin();
0559         auto _end = __destination->fWatchers.end();
0560 
0561         for (; it != _end; it++)
0562         {
0563           for(iterator it2 = this->begin() ;
0564               it2 != this->end(); ++it2)
0565           {
0566             (*it)->NotifyAddObject(*it2, this);
0567           }
0568         }
0569       }
0570 
0571       node* lastNode = __destination->fBoundary.GetPrevious();
0572       lastNode->SetNext(fBoundary.GetNext());
0573       fBoundary.GetNext()->SetPrevious(lastNode);
0574       __destination->fBoundary.SetPrevious(fBoundary.GetPrevious());
0575       fBoundary.GetPrevious()->SetNext(&__destination->fBoundary);
0576 
0577       __destination->fNbObjects += this->fNbObjects;
0578     }
0579 
0580     fNbObjects = 0;
0581     this->fBoundary.SetPrevious(&this->fBoundary);
0582     this->fBoundary.SetNext(&this->fBoundary);
0583 
0584     fListRef->fpList = __destination;
0585   }
0586 
0587 //____________________________________________________________
0588 //
0589 //                      G4FastList<OBJECT> Utils
0590 //____________________________________________________________
0591 
0592 template<class OBJECT>
0593   G4FastListNode<OBJECT>* G4FastList<OBJECT>::__GetNode(OBJECT* __obj)
0594   {
0595     G4FastListNode<OBJECT>* __node = GetNode(__obj);
0596     // TODO : complete the exception
0597     if (__node == nullptr)
0598     {
0599       G4ExceptionDescription exceptionDescription;
0600       exceptionDescription << "The object ";
0601       exceptionDescription << " was not connected to any trackList ";
0602       G4Exception("G4FastList<OBJECT>::Unflag", "G4FastList003",
0603                   FatalErrorInArgument, exceptionDescription);
0604       return nullptr;
0605     }
0606     return __node;
0607   }
0608 
0609 template<class OBJECT>
0610   G4FastListNode<OBJECT>* G4FastList<OBJECT>::GetNode(OBJECT* __obj)
0611   {
0612     G4FastListNode<OBJECT>* __node = __obj->GetListNode();
0613     return __node;
0614   }
0615 
0616 template<class OBJECT>
0617   void G4FastList<OBJECT>::SetNode(OBJECT* __obj,
0618                                    G4FastListNode<OBJECT>* __node)
0619   {
0620     __obj->SetListNode(__node);
0621   }
0622 
0623 template<class OBJECT>
0624   G4FastList<OBJECT>* G4FastList<OBJECT>::GetList(OBJECT* __obj)
0625   {
0626     G4FastListNode<OBJECT>* __node = GetNode(__obj);
0627 
0628     if (__node == 0) return 0;
0629     if (__node->fListRef == nullptr) return 0;
0630 
0631     return __node->fListRef->fpTrackList;
0632   }
0633 
0634 template<class OBJECT>
0635   G4FastList<OBJECT>*
0636   G4FastList<OBJECT>::GetList(G4FastListNode<OBJECT>* __node)
0637   {
0638     if (__node == nullptr) return nullptr;
0639     if (__node->fListRef == nullptr) return nullptr;
0640 
0641     return __node->fListRef->fpList;
0642   }
0643 
0644 template<class OBJECT>
0645   void G4FastList<OBJECT>::Pop(OBJECT* __obj)
0646   {
0647     G4FastListNode<OBJECT>* __node = G4FastList<OBJECT>::GetNode(__obj);
0648     G4FastList<OBJECT>* __list = G4FastList<OBJECT>::GetList(__node);
0649     if (__list) __list->pop(__node);
0650   }
0651 
0652 //#endif /* G4FASTLIST_ICC_*/