Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/processes/electromagnetic/dna/management/include/G4ManyFastLists.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  * G4ManyFastLists.hh
 28  *
 29  *  Created on: 17 nov. 2014
 30  *      Author: kara
 31  */
 32 
 33 #pragma once
 34 
 35 #include "G4FastList.hh"
 36 #include <set>
 37 
 38 template<class OBJECT>
 39   struct G4ManyFastLists_iterator;
 40 
 41 /*
 42  * Roll over many list as if it was one
 43  */
 44 template<class OBJECT>
 45   class G4ManyFastLists : public G4FastList<OBJECT>::Watcher
 46   {
 47   protected:
 48     using ManyLists = G4FastList<G4FastList<OBJECT>>;
 49     ManyLists fAssociatedLists;
 50     // TODO use "marked list" insted of vector
 51 
 52     using WatcherSet = std::set<typename G4FastList<OBJECT>::Watcher*,
 53         sortWatcher<OBJECT>>;
 54     WatcherSet* fMainListWatchers;
 55 
 56   public:
 57     using iterator = G4ManyFastLists_iterator<OBJECT>;
 58 
 59     G4ManyFastLists() : G4FastList<OBJECT>::Watcher(),
 60         fAssociatedLists(), fMainListWatchers(nullptr)
 61     {
 62     }
 63 
 64     ~G4ManyFastLists() override = default;
 65 
 66     virtual void NotifyDeletingList(G4FastList<OBJECT>* __list)
 67     {
 68       fAssociatedLists.pop(__list);
 69     }
 70 
 71     void AddGlobalWatcher(typename G4FastList<OBJECT>::Watcher* watcher)
 72     {
 73       if(fMainListWatchers == nullptr)
 74       {
 75         fMainListWatchers = new WatcherSet();
 76       }
 77 
 78       fMainListWatchers->insert(watcher);
 79 
 80       typename ManyLists::iterator it = fAssociatedLists.begin();
 81       typename ManyLists::iterator _end = fAssociatedLists.end();
 82 
 83       for(;it != _end ;++it)
 84       {
 85         watcher->Watch(*it);
 86 //        (*it)->AddWatcher(watcher);
 87 //        (*it)->AddWatcher(watcher);
 88       }
 89     }
 90 
 91     inline void Add(G4FastList<OBJECT>* __list)
 92     {
 93       if (__list == nullptr) return;
 94       fAssociatedLists.push_back(__list); // TODO use the table doubling tech
 95       //__list->AddWatcher(this);
 96       this->Watch(__list);
 97 
 98       if(fMainListWatchers == nullptr) return;
 99 
100       auto it_watcher = fMainListWatchers->begin();
101       auto end_watcher = fMainListWatchers->end();
102 
103 //      G4cout << "G4ManyFastLists::Add -- N watchers ="
104 //             << fMainListWatchers->size()
105 //             << G4endl;
106 
107       for(;it_watcher != end_watcher ;++it_watcher)
108       {
109 //        G4cout << " *** *** *** WATCH --- "
110 //                           << (*it_watcher)->GetWatcherName()
111 //                           << G4endl;
112         (*it_watcher)->Watch(__list);
113       }
114 
115       if(__list->empty() == false)
116       {
117         it_watcher = fMainListWatchers->begin();
118 
119         for(;it_watcher != end_watcher ;++it_watcher)
120         {
121           typename G4FastList<OBJECT>::iterator it_obj = __list->begin();
122           for(;it_obj != __list->end() ;++it_obj)
123           {
124 //            G4cout << " *** *** *** NOTIFY ADD OBJ --- "
125 //                   << (*it_watcher)->GetWatcherName()
126 //                   << G4endl;
127 
128             (*it_watcher)->NotifyAddObject(*it_obj,__list);
129           }
130         }
131       }
132 //      else
133 //      {
134 //        G4cout << "__list->empty() == true" << G4endl;
135 //      }
136 
137       /*
138       typename ManyLists::const_iterator __it = fAssociatedLists
139           .begin();
140       typename ManyLists::const_iterator __end = fAssociatedLists
141           .end();
142       for (; __it != __end; __it++)
143       {
144         assert(*__it);
145       }
146       */
147     }
148 
149     inline void Remove(G4FastList<OBJECT>* __list)
150     {
151       if (__list == nullptr) return;
152       fAssociatedLists.pop(__list); // TODO use the table doubling tech
153       __list->RemoveWatcher(this);
154       this->StopWatching(__list);
155 
156       auto it = fMainListWatchers->begin();
157       auto _end = fMainListWatchers->end();
158 
159       for(;it != _end ;++it)
160       {
161         (*it)->StopWatching(__list);
162       }
163 
164 //      typename ManyLists::node* __node = __list->GetListNode();
165 //      if(__node)
166 //      {
167 //        __list->SetListNode(0);
168 //        delete __node;
169 //      }
170     }
171 
172     inline bool Holds(OBJECT* __track) const
173     {
174       typename ManyLists::const_iterator __it = fAssociatedLists.begin();
175       typename ManyLists::const_iterator __end = fAssociatedLists.end();
176       for (; __it != __end; __it++)
177         if ((*__it)->Holds(__track)) return true;
178       return false;
179     }
180 
181     inline size_t size() const
182     {
183       size_t __size(0);
184       for (auto __it : fAssociatedLists)
185       {
186         __size += __it->size();
187       }
188       return __size;
189     }
190 
191     inline void RemoveLists()
192     {
193       typename ManyLists::iterator __it = fAssociatedLists.begin();
194       typename ManyLists::iterator __end = fAssociatedLists.end();
195       for (; __it != __end; __it++)
196       {
197         if (*__it)
198         {
199           (*__it)->clear();
200           typename ManyLists::iterator next = __it;
201           next++;
202           Remove(*__it);
203           typename ManyLists::node* __node = __it.GetNode();
204           if(__node)
205           {
206             __node->GetObject()->SetListNode(nullptr);
207             delete __node;
208           }
209 //          delete (*__it);
210 
211           __it = next;
212         }
213       }
214       fAssociatedLists.clear();
215     }
216 
217     inline void ClearLists()
218     {
219       typename ManyLists::iterator __it = fAssociatedLists.begin();
220       typename ManyLists::iterator __end = fAssociatedLists.end();
221       for (; __it != __end; __it++)
222         if (*__it) (*__it)->clear();
223     }
224 
225     inline iterator begin();
226     inline iterator end();
227 
228     void pop(OBJECT*);
229   };
230 
231 template<class OBJECT>
232   struct G4ManyFastLists_iterator
233   {
234     using ManyLists = G4FastList<G4FastList<OBJECT>>;
235 
236     using _Self = G4ManyFastLists_iterator;
237     using _Node = G4FastListNode<OBJECT>;
238 
239     G4FastList_iterator<OBJECT> fIterator;
240     typename ManyLists::iterator fCurrentListIt;
241     ManyLists* fLists;
242 
243   private:
244     G4ManyFastLists_iterator() = default;
245 
246   public:
247     explicit G4ManyFastLists_iterator(G4FastList_iterator<OBJECT> __x,
248                                       typename ManyLists::iterator __it,
249                                       ManyLists* __lists) :
250         fIterator(__x), fCurrentListIt(__it), fLists(__lists)
251     {
252     }
253 
254     G4ManyFastLists_iterator(const G4ManyFastLists_iterator& __x) = default;
255     _Self& operator=(const G4ManyFastLists_iterator& __x) = default;
256 
257     _Node* GetNode()
258     {
259       return fIterator.GetNode();
260     }
261 
262     G4FastList<OBJECT>* GetTrackList()
263     {
264       return *fCurrentListIt;
265     }
266 
267     OBJECT* operator*()
268     {
269       return *fIterator;
270     }
271     const OBJECT* operator*() const
272     {
273       return *fIterator;
274     }
275     OBJECT* operator->()
276     {
277       return *fIterator;
278     }
279     const OBJECT* operator->() const
280     {
281       return *fIterator;
282     }
283 
284     _Self UpdateToNextValidList();
285     _Self& operator++();
286 
287     _Self operator++(int)
288     {
289       return operator++();
290     }
291 
292     _Self&
293     operator--()
294     {
295       if (fLists->empty())
296       {
297         fIterator = G4FastList_iterator<OBJECT>();
298         return *this;
299       }
300       if (fCurrentListIt == fLists->begin())
301       {
302         if (fIterator == (*fCurrentListIt)->begin())
303         {
304           fIterator = G4FastList_iterator<OBJECT>();
305           return *this;
306         }
307       }
308 
309       if (fCurrentListIt == fLists->end())
310       {
311         fCurrentListIt--;
312         fIterator = (*fCurrentListIt)->end();
313       }
314       else if (fIterator == (*fCurrentListIt)->begin())
315       {
316         fCurrentListIt--;
317         fIterator = (*fCurrentListIt)->end();
318       }
319 
320       fIterator--;
321 
322       while (((*fCurrentListIt)->empty() || fIterator.GetNode() == nullptr
323               || fIterator.GetNode()->GetObject() == nullptr)
324              && fCurrentListIt != fLists->begin())
325       {
326         fIterator = (*fCurrentListIt)->begin();
327         fCurrentListIt--;
328         fIterator = (*fCurrentListIt)->end();
329         fIterator--;
330       }
331 
332       if (fIterator.GetNode() == nullptr && fCurrentListIt == fLists->begin())
333       {
334         fIterator = G4FastList_iterator<OBJECT>();
335         return *this;
336       }
337 
338       return *this;
339     }
340 
341     _Self operator--(int)
342     {
343       return operator--();
344     }
345 
346     G4bool operator==(const _Self& __x) const
347     {
348       return (fIterator == __x.fIterator && fCurrentListIt == __x.fCurrentListIt);
349     } // Fast check
350 
351     G4bool operator!=(const _Self& __x) const
352     {
353       return !(this->operator ==(__x));
354     }
355 
356   protected:
357     void HasReachedEnd()
358     {
359       if (fLists->empty() == false)
360       {
361         fIterator = (*(fLists->end()--))->end();
362       }
363       else
364       {
365         fIterator = G4FastList_iterator<OBJECT>();
366       }
367     }
368   };
369 
370 template<class OBJECT>
371   typename G4ManyFastLists<OBJECT>::iterator G4ManyFastLists<OBJECT>::begin()
372   {
373     if (fAssociatedLists.empty())
374     {
375       return G4ManyFastLists_iterator<OBJECT>(G4FastList_iterator<OBJECT>(),
376                                              fAssociatedLists.end(),
377                                              &fAssociatedLists);
378     }
379 
380     typename G4FastList<OBJECT>::iterator trackList_it;
381     int i = 0;
382 
383     typename ManyLists::iterator it = fAssociatedLists.begin();
384     typename ManyLists::iterator _end = fAssociatedLists.end();
385 
386     while (it != _end)
387     {
388       if (*it && (*it)->empty() == false)
389       {
390         trackList_it = (*it)->begin();
391         break;
392       }
393       i++;
394       it++;
395     };
396 
397     if (i == fAssociatedLists.size() || it == _end)
398     {
399       return end();
400     }
401 
402     return G4ManyFastLists_iterator<OBJECT>(trackList_it,
403 //                                           fAssociatedLists.begin(),
404                                             it,
405                                            &fAssociatedLists);
406   }
407 
408 template<class OBJECT>
409 typename G4ManyFastLists<OBJECT>::iterator G4ManyFastLists<OBJECT>::end()
410   {
411     if (fAssociatedLists.empty())
412     {
413       return G4ManyFastLists_iterator<OBJECT>(G4FastList_iterator<OBJECT>(),
414                                              fAssociatedLists.end(),
415                                              &fAssociatedLists);
416     }
417 
418     return G4ManyFastLists_iterator<OBJECT>((fAssociatedLists.end()--)->end(),
419                                            fAssociatedLists.end(),
420                                            &fAssociatedLists);
421   }
422 
423 #include "G4ManyFastLists.icc"
424