Geant4 Cross Reference

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

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 (kara (AT) cenbg . in2p3 . fr)
 28 //
 29 // History:
 30 // -----------
 31 // 10 Oct 2011 M.Karamitros created
 32 //
 33 // -------------------------------------------------------------------
 34 
 35 //#ifndef G4FASTLIST_ICC_
 36 //#define G4FASTLIST_ICC_
 37 
 38 //***********************************************************
 39 // TrackList_iterator
 40 template<class OBJECT>
 41   OBJECT*
 42   G4FastList_iterator<OBJECT>::operator*()
 43   {
 44     if (fpNode == nullptr) return nullptr;
 45     return fpNode->GetObject();
 46   }
 47 
 48 template<class OBJECT>
 49   OBJECT*
 50   G4FastList_iterator<OBJECT>::operator->()
 51   {
 52     if (fpNode == nullptr) return nullptr;
 53     return fpNode->GetObject();
 54   }
 55 
 56 template<class OBJECT>
 57   const OBJECT*
 58   G4FastList_iterator<OBJECT>::operator*() const
 59   {
 60     if (fpNode == 0) return 0;
 61     return fpNode->GetObject();
 62   }
 63 
 64 template<class OBJECT>
 65   const OBJECT*
 66   G4FastList_iterator<OBJECT>::operator->() const
 67   {
 68     if (fpNode == 0) return 0;
 69     return fpNode->GetObject();
 70   }
 71 
 72 //***********************************************************
 73 // TrackNodeList
 74 
 75 template<class OBJECT>
 76   G4FastListNode<OBJECT>::G4FastListNode(OBJECT* track) :
 77       fpObject(track), fpPrevious(nullptr), fpNext(nullptr)
 78   {
 79     fAttachedToList = false;
 80   }
 81 
 82 template<class OBJECT>
 83   G4FastListNode<OBJECT>::~G4FastListNode()
 84   {
 85     if (fListRef && fListRef->fpList)
 86     {
 87       fListRef->fpList->pop(this);
 88     }
 89   }
 90 
 91 template<class OBJECT>
 92   void G4FastListNode<OBJECT>::DetachYourSelf()
 93   {
 94     if(fpObject)
 95     {
 96       fpObject->SetListNode(nullptr);
 97     }
 98   }
 99 
100 //***********************************************************
101 
102 template<class OBJECT>
103   G4FastList<OBJECT>::G4FastList() :
104       fBoundary()
105   {
106     fListRef.reset(new _ListRef<G4FastList<OBJECT> >(this));
107     fNbObjects = 0;
108     fBoundary.SetPrevious(&fBoundary);
109     fBoundary.SetNext(&fBoundary);
110     fBoundary.fAttachedToList = true;
111     fpNodeInManyLists = nullptr;
112   }
113 
114 // should not be used
115 template<class OBJECT>
116   G4FastList<OBJECT>::G4FastList(const G4FastList<OBJECT>& /*other*/) :
117       fBoundary()
118   {
119     // One track should not belong to two different trackLists
120     fNbObjects = 0;
121     fpNodeInManyLists = 0;
122   }
123 
124 template<class OBJECT>
125   G4FastList<OBJECT>& G4FastList<OBJECT>::operator=(const G4FastList<OBJECT>& other)
126   {
127     // One track should not belong to two different trackList
128     if (this == &other) return *this; // handle self assignment
129     //assignment operator
130     return *this;
131   }
132 
133 template<class OBJECT>
134   G4FastList<OBJECT>::~G4FastList()
135   {
136     if (fNbObjects != 0)
137     {
138       G4FastListNode<OBJECT> * __stackedTrack = fBoundary.GetNext();
139       G4FastListNode<OBJECT> * __nextStackedTrack;
140 
141       // delete tracks in the stack
142       while (__stackedTrack && __stackedTrack != &(fBoundary))
143       {
144         __nextStackedTrack = __stackedTrack->GetNext();
145         OBJECT* __obj = __stackedTrack->GetObject();
146 
147         delete __stackedTrack;
148         __stackedTrack = nullptr;
149 
150         if (__obj)
151         {
152           //////////////
153           DeleteObject(__obj);
154           __obj = nullptr;
155           //////////////
156         }
157         __stackedTrack = __nextStackedTrack;
158       }
159     }
160     fNbObjects = 0;
161 
162     auto it = fWatchers.begin();
163     auto _end = fWatchers.end();
164 
165     for (; it != _end; it++)
166     {
167       (*it)->NotifyDeletingList(this);
168       (*it)->StopWatching(this, false);
169     }
170 
171     if (fpNodeInManyLists)
172     {
173       delete fpNodeInManyLists;
174       fpNodeInManyLists = nullptr;
175     }
176   }
177 
178 template<class OBJECT>
179   bool G4FastList<OBJECT>::empty() const
180   {
181     return (fNbObjects == 0);
182   }
183 
184 template<class OBJECT>
185   typename G4FastList<OBJECT>::iterator G4FastList<OBJECT>::begin()
186   {
187     return iterator(fBoundary.GetNext());
188   }
189 
190 template<class OBJECT>
191   typename G4FastList<OBJECT>::const_iterator G4FastList<OBJECT>::begin() const
192   {
193     return const_iterator(fBoundary.GetNext());
194   }
195 
196 template<class OBJECT>
197   typename G4FastList<OBJECT>::iterator G4FastList<OBJECT>::end()
198   {
199     return iterator(&(fBoundary));
200   }
201 
202 template<class OBJECT>
203   typename G4FastList<OBJECT>::const_iterator G4FastList<OBJECT>::end() const
204   {
205     return const_iterator(&(fBoundary));
206   }
207 // return an iterator that contains an empty node
208 // use for boundary checking only
209 
210 template<class OBJECT>
211   void G4FastList<OBJECT>::push_front(OBJECT* __obj)
212   {
213     insert(begin(), __obj);
214   }
215 
216 template<class OBJECT>
217   void G4FastList<OBJECT>::push_back(OBJECT* __obj)
218   {
219     insert(end(), __obj);
220   }
221 
222 template<class OBJECT>
223   bool G4FastList<OBJECT>::Holds(const OBJECT* __obj) const
224   {
225     node* __node = GetNode(__obj);
226     if(__node == 0) return false;
227     return (__node->fListRef->fpList == this);
228   }
229 
230 // TODO: A revoir
231 template<class OBJECT>
232   G4FastListNode<OBJECT>* G4FastList<OBJECT>::Flag(OBJECT* __obj)
233   {
234     G4FastListNode<OBJECT>* __node = GetNode(__obj);
235 
236     if (__node != nullptr)
237     {
238       // Suggestion move the node to this list
239       if (__node->fAttachedToList)
240       {
241         G4ExceptionDescription exceptionDescription;
242         exceptionDescription << "An object";
243         exceptionDescription << " is already attached to a TrackList ";
244         G4Exception("G4FastList<OBJECT>::Flag", "G4FastList001",
245                     FatalErrorInArgument, exceptionDescription);
246       }
247     }
248     else
249     {
250       __node = new G4FastListNode<OBJECT>(__obj);
251       SetNode(__obj,__node);
252     }
253 
254     __node->fAttachedToList = true;
255     __node->fListRef = fListRef;
256     return __node;
257   }
258 
259 template<class OBJECT>
260   G4FastListNode<OBJECT>* G4FastList<OBJECT>::CreateNode(OBJECT* __obj)
261   {
262     G4FastListNode<OBJECT>* __listNode = Flag(__obj);
263     return __listNode;
264   }
265 
266 template<class OBJECT>
267   void G4FastList<OBJECT>::Hook(G4FastListNode<OBJECT>* __position,
268                                 G4FastListNode<OBJECT>* __toHook)
269   {
270     /*
271      __toHook->SetNext(__position);
272      __toHook->SetPrevious(__position->GetPrevious());
273      __position->GetPrevious()->SetNext(__toHook);
274      __position->SetPrevious(__toHook);
275      */
276     G4FastListNode<OBJECT>* __previous = __position->GetPrevious();
277     __toHook->SetPrevious(__previous);
278     __toHook->SetNext(__position);
279     __position->SetPrevious(__toHook);
280     __previous->SetNext(__toHook);
281 
282     /*
283      if (fNbObjects == 0)
284      {
285      // DEBUG
286      //        G4cout << "fNbObjects == 0" << G4endl;
287      fpStart = __toHook;
288      fpFinish = __toHook;
289      __toHook->SetNext(&fBoundary);
290      __toHook->SetPrevious(&fBoundary);
291      //fBoundary.SetNext(__toHook);
292      fBoundary.SetPrevious(__toHook);
293      } else if (__position == &fBoundary)
294      {
295      // DEBUG
296      //        G4cout << "__position == &fBoundary" << G4endl;
297      fpFinish->SetNext(__toHook);
298      __toHook->SetPrevious(fpFinish);
299 
300      __toHook->SetNext(&fBoundary);
301      fBoundary.SetPrevious(__toHook);
302 
303      fpFinish = __toHook;
304      } else if (__position == fpStart)
305      {
306      // DEBUG
307      //        G4cout << "__position == fStart" << G4endl;
308      __toHook->SetPrevious(&fBoundary);
309      //fBoundary.SetNext(__toHook);
310      __toHook->SetNext(fpStart);
311      fpStart->SetPrevious(__toHook);
312      fpStart = __toHook;
313      } else
314      {
315      // DEBUG
316      //        G4cout << "else" << G4endl;
317      G4FastListNode<OBJECT>* __previous = __position->GetPrevious();
318      __toHook->SetPrevious(__previous);
319      __toHook->SetNext(__position);
320      __position->SetPrevious(__toHook);
321      __previous->SetNext(__toHook);
322      }
323      */
324     fNbObjects++;
325 
326     if(fWatchers.empty() == false)
327     {
328       auto it = fWatchers.begin();
329       auto _end = fWatchers.end();
330 
331       for (; it != _end; it++)
332       {
333         (*it)->NotifyAddObject(__toHook->GetObject(), this);
334       }
335     }
336   }
337 
338 template<class OBJECT>
339   void G4FastListNode<OBJECT>::UnHook()
340   {
341     G4FastListNode<OBJECT>* __next_node = this->fpNext;
342     G4FastListNode<OBJECT>* __prev_node = this->fpPrevious;
343 
344     if (__prev_node)
345     {
346       __prev_node->fpNext = __next_node;
347     }
348 
349     if (__next_node)
350     {
351       __next_node->fpPrevious = __prev_node;
352     }
353     fpNext = nullptr;
354     fpPrevious = nullptr;
355   }
356 
357 template<class OBJECT>
358   void G4FastList<OBJECT>::Unhook(G4FastListNode<OBJECT>* __toUnHook)
359   {
360     __toUnHook->UnHook();
361 
362     fNbObjects--;
363 
364     auto it = fWatchers.begin();
365     auto _end = fWatchers.end();
366 
367     for (; it != _end; it++)
368     {
369       (*it)->NotifyRemoveObject(__toUnHook->GetObject(), this);
370     }
371   }
372 
373 template<class OBJECT>
374   typename G4FastList<OBJECT>::iterator
375   G4FastList<OBJECT>::insert(typename G4FastList<OBJECT>::iterator __position,
376                              OBJECT* __obj)
377   {
378     G4FastListNode<OBJECT>* __node = CreateNode(__obj);
379     Hook(__position.fpNode, __node);
380     return iterator(__node);
381   }
382 
383 //____________________________________________________________________
384 //
385 //                      WITHDRAW FROM LIST
386 //____________________________________________________________________
387 
388 template<class OBJECT>
389   void G4FastList<OBJECT>::CheckFlag(G4FastListNode<OBJECT>* __node)
390   {
391     if (__node->fListRef->fpList != this)
392     {
393       G4ExceptionDescription exceptionDescription;
394       exceptionDescription << "The object "
395       << " is not correctly linked to a G4FastList." << G4endl
396       << "You are probably trying to withdraw this object "
397       << "from the list but it probably does not belong to "
398       << "this fast list." << G4endl;
399       G4Exception("G4FastList<OBJECT>::CheckFlag", "G4FastList002",
400                   FatalErrorInArgument, exceptionDescription);
401     }
402   }
403 
404 template<class OBJECT>
405   G4FastListNode<OBJECT>* G4FastList<OBJECT>::Unflag(OBJECT* __obj)
406   {
407     G4FastListNode<OBJECT>* __node = __GetNode(__obj);
408     CheckFlag(__node);
409     __node->fAttachedToList = false;
410     __node->fListRef.reset();
411     return __node;
412   }
413 
414 template<class OBJECT>
415   void G4FastList<OBJECT>::Unflag(G4FastListNode<OBJECT>* __node)
416   {
417     CheckFlag(__node);
418     __node->fAttachedToList = false;
419     __node->fListRef.reset();
420     return;
421   }
422 
423 template<class OBJECT>
424   OBJECT* G4FastList<OBJECT>::pop_back()
425   {
426     if (fNbObjects == 0) return 0;
427     G4FastListNode<OBJECT> * __aNode = fBoundary.GetPrevious();
428     Unhook(__aNode);
429     Unflag(__aNode);
430     return __aNode->GetObject();
431   }
432 
433 template<class OBJECT>
434   typename G4FastList<OBJECT>::iterator G4FastList<OBJECT>::pop(OBJECT* __obj)
435   {
436     G4FastListNode<OBJECT>* __node = Unflag(__obj);
437     iterator __next(__node->GetNext());
438     Unhook(__node);
439     return __next;
440   }
441 
442 template<class OBJECT>
443   typename G4FastList<OBJECT>::iterator
444   G4FastList<OBJECT>::pop(G4FastListNode<OBJECT>* __node)
445   {
446     Unflag(__node);
447     iterator __next(__node->GetNext());
448     Unhook(__node);
449     return __next;
450   }
451 
452 template<class OBJECT>
453   typename G4FastList<OBJECT>::iterator G4FastList<OBJECT>::erase(OBJECT* __obj)
454   {
455     G4FastListNode<OBJECT>* __next_node = EraseListNode(__obj);
456     //////////////////
457     DeleteObject(__obj);
458     __obj = nullptr;
459     //////////////////
460     iterator __next(__next_node);
461     return __next;
462   }
463 
464 template<class OBJECT>
465   G4FastListNode<OBJECT>* G4FastList<OBJECT>::EraseListNode(OBJECT* __obj)
466   {
467     G4FastListNode<OBJECT>* __node = Unflag(__obj);
468     __node->DetachYourSelf();
469     G4FastListNode<OBJECT>* __next = __node->GetNext();
470     Unhook(__node);
471     delete __node;
472     return __next;
473   }
474 
475 template<class OBJECT>
476   void G4FastList<OBJECT>::DeleteObject(OBJECT*)
477   {
478 //    delete __obj;
479   }
480 
481 template<class OBJECT>
482   void G4FastList<OBJECT>::remove(OBJECT* __obj)
483   {
484     this->erase(__obj);
485   }
486 
487 template<class OBJECT>
488   typename G4FastList<OBJECT>::iterator G4FastList<OBJECT>::pop(iterator __first,
489                                                                 iterator __last)
490   {
491     if (fNbObjects == 0) return iterator(&fBoundary);
492 
493     while (__first != __last)
494     {
495       if (__first.fpNode) __first = pop(*__first);
496     }
497     return __last;
498   }
499 
500 template<class OBJECT>
501   typename G4FastList<OBJECT>::iterator G4FastList<OBJECT>::erase(iterator __first,
502                                                                   iterator __last)
503   {
504     if (fNbObjects == 0) return iterator(&fBoundary);
505 
506     while (__first != __last)
507     {
508       if (__first.fpNode) __first = erase(*__first);
509     }
510     return __last;
511   }
512 
513 template<class OBJECT>
514   void G4FastList<OBJECT>::clear()
515   {
516     erase(begin(), end());
517   }
518 
519 template<class OBJECT>
520   void G4FastList<OBJECT>::transferTo(G4FastList<OBJECT>* __destination)
521   {
522     if (fNbObjects == 0) return;
523 
524     if (__destination->fNbObjects == 0)
525     {
526 
527       if(__destination->fWatchers.empty()==false)
528       {
529         auto it = __destination->fWatchers.begin();
530         auto _end = __destination->fWatchers.end();
531 
532 //        G4cout << "G4FastList<OBJECT>::transferTo --- Watcher size = "
533 //               << __destination->fWatchers.size()
534 //               << G4endl;
535 
536         for (; it != _end; it++)
537         {
538           for(iterator it2 = this->begin() ;
539               it2 != this->end(); ++it2
540           )
541           {
542             (*it)->NotifyAddObject(*it2, this);
543           }
544         }
545       }
546 
547       __destination->fNbObjects = this->fNbObjects;
548 
549       __destination->fBoundary.SetNext(fBoundary.GetNext());
550       __destination->fBoundary.SetPrevious(fBoundary.GetPrevious());
551       fBoundary.GetNext()->SetPrevious(&__destination->fBoundary);
552       fBoundary.GetPrevious()->SetNext(&__destination->fBoundary);
553     }
554     else
555     {
556       if(__destination->fWatchers.empty()==false)
557       {
558         auto it = __destination->fWatchers.begin();
559         auto _end = __destination->fWatchers.end();
560 
561         for (; it != _end; it++)
562         {
563           for(iterator it2 = this->begin() ;
564               it2 != this->end(); ++it2)
565           {
566             (*it)->NotifyAddObject(*it2, this);
567           }
568         }
569       }
570 
571       node* lastNode = __destination->fBoundary.GetPrevious();
572       lastNode->SetNext(fBoundary.GetNext());
573       fBoundary.GetNext()->SetPrevious(lastNode);
574       __destination->fBoundary.SetPrevious(fBoundary.GetPrevious());
575       fBoundary.GetPrevious()->SetNext(&__destination->fBoundary);
576 
577       __destination->fNbObjects += this->fNbObjects;
578     }
579 
580     fNbObjects = 0;
581     this->fBoundary.SetPrevious(&this->fBoundary);
582     this->fBoundary.SetNext(&this->fBoundary);
583 
584     fListRef->fpList = __destination;
585   }
586 
587 //____________________________________________________________
588 //
589 //                      G4FastList<OBJECT> Utils
590 //____________________________________________________________
591 
592 template<class OBJECT>
593   G4FastListNode<OBJECT>* G4FastList<OBJECT>::__GetNode(OBJECT* __obj)
594   {
595     G4FastListNode<OBJECT>* __node = GetNode(__obj);
596     // TODO : complete the exception
597     if (__node == nullptr)
598     {
599       G4ExceptionDescription exceptionDescription;
600       exceptionDescription << "The object ";
601       exceptionDescription << " was not connected to any trackList ";
602       G4Exception("G4FastList<OBJECT>::Unflag", "G4FastList003",
603                   FatalErrorInArgument, exceptionDescription);
604       return nullptr;
605     }
606     return __node;
607   }
608 
609 template<class OBJECT>
610   G4FastListNode<OBJECT>* G4FastList<OBJECT>::GetNode(OBJECT* __obj)
611   {
612     G4FastListNode<OBJECT>* __node = __obj->GetListNode();
613     return __node;
614   }
615 
616 template<class OBJECT>
617   void G4FastList<OBJECT>::SetNode(OBJECT* __obj,
618                                    G4FastListNode<OBJECT>* __node)
619   {
620     __obj->SetListNode(__node);
621   }
622 
623 template<class OBJECT>
624   G4FastList<OBJECT>* G4FastList<OBJECT>::GetList(OBJECT* __obj)
625   {
626     G4FastListNode<OBJECT>* __node = GetNode(__obj);
627 
628     if (__node == 0) return 0;
629     if (__node->fListRef == nullptr) return 0;
630 
631     return __node->fListRef->fpTrackList;
632   }
633 
634 template<class OBJECT>
635   G4FastList<OBJECT>*
636   G4FastList<OBJECT>::GetList(G4FastListNode<OBJECT>* __node)
637   {
638     if (__node == nullptr) return nullptr;
639     if (__node->fListRef == nullptr) return nullptr;
640 
641     return __node->fListRef->fpList;
642   }
643 
644 template<class OBJECT>
645   void G4FastList<OBJECT>::Pop(OBJECT* __obj)
646   {
647     G4FastListNode<OBJECT>* __node = G4FastList<OBJECT>::GetNode(__obj);
648     G4FastList<OBJECT>* __list = G4FastList<OBJECT>::GetList(__node);
649     if (__list) __list->pop(__node);
650   }
651 
652 //#endif /* G4FASTLIST_ICC_*/
653